From 3e011a9c4ac8388bdd50256f961a564b832126b0 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 5 Jun 2020 10:25:36 +0100 Subject: [PATCH 01/38] update host and wsf files --- .../stack/ble-host/include/att_api.h | 104 +- .../stack/ble-host/include/att_defs.h | 64 +- .../stack/ble-host/include/att_handler.h | 34 +- .../stack/ble-host/include/att_uuid.h | 42 +- .../stack/ble-host/include/dm_api.h | 727 ++++++++- .../stack/ble-host/include/dm_handler.h | 34 +- .../stack/ble-host/include/eatt_api.h | 454 ++++++ .../stack/ble-host/include/hci_api.h | 710 +++++++- .../stack/ble-host/include/hci_cmd.h | 34 +- .../stack/ble-host/include/hci_core.h | 78 +- .../stack/ble-host/include/hci_drv.h | 34 +- .../stack/ble-host/include/hci_evt.h | 34 +- .../stack/ble-host/include/hci_handler.h | 34 +- .../stack/ble-host/include/hci_tr.h | 34 +- .../stack/ble-host/include/l2c_api.h | 119 +- .../stack/ble-host/include/l2c_defs.h | 56 +- .../stack/ble-host/include/l2c_handler.h | 34 +- .../stack/ble-host/include/sec_api.h | 37 +- .../stack/ble-host/include/smp_api.h | 36 +- .../stack/ble-host/include/smp_defs.h | 34 +- .../stack/ble-host/include/smp_handler.h | 34 +- .../stack/ble-host/include/svc_core.h | 171 -- .../ble-host/sources/hci/common/hci_core.c | 205 ++- .../ble-host/sources/hci/dual_chip/hci_cmd.c | 103 +- .../sources/hci/dual_chip/hci_cmd_ae.c | 38 +- .../sources/hci/dual_chip/hci_cmd_bis.c | 141 ++ .../sources/hci/dual_chip/hci_cmd_cis.c | 173 ++ .../sources/hci/dual_chip/hci_cmd_cte.c | 34 +- .../sources/hci/dual_chip/hci_cmd_iso.c | 284 ++++ .../sources/hci/dual_chip/hci_cmd_past.c | 34 +- .../sources/hci/dual_chip/hci_cmd_phy.c | 34 +- .../sources/hci/dual_chip/hci_core_ps.c | 72 +- .../sources/hci/dual_chip/hci_core_ps.h | 34 +- .../ble-host/sources/hci/dual_chip/hci_evt.c | 672 +++++++- .../sources/hci/dual_chip/hci_vs_ae.c | 34 +- .../ble-host/sources/sec/common/sec_aes.c | 34 +- .../ble-host/sources/sec/common/sec_aes_rev.c | 137 ++ .../ble-host/sources/sec/common/sec_ccm_hci.c | 36 +- .../sources/sec/common/sec_cmac_hci.c | 34 +- .../sources/sec/common/sec_ecc_debug.c | 160 ++ .../ble-host/sources/sec/common/sec_ecc_hci.c | 34 +- .../ble-host/sources/sec/common/sec_main.c | 53 +- .../ble-host/sources/sec/common/sec_main.h | 36 +- .../stack/ble-host/sources/sec/pal/sec_ccm.c | 172 -- .../ble-host/sources/stack/att/att_eatt.c | 938 +++++++++++ .../ble-host/sources/stack/att/att_eatt.h | 84 + .../ble-host/sources/stack/att/att_main.c | 177 +- .../ble-host/sources/stack/att/att_main.h | 95 +- .../ble-host/sources/stack/att/att_sign.h | 34 +- .../ble-host/sources/stack/att/att_uuid.c | 39 +- .../ble-host/sources/stack/att/attc_disc.c | 199 ++- .../ble-host/sources/stack/att/attc_eatt.c | 817 ++++++++++ .../ble-host/sources/stack/att/attc_main.c | 226 +-- .../ble-host/sources/stack/att/attc_main.h | 70 +- .../ble-host/sources/stack/att/attc_proc.c | 137 +- .../ble-host/sources/stack/att/attc_read.c | 36 +- .../ble-host/sources/stack/att/attc_sign.c | 61 +- .../ble-host/sources/stack/att/attc_write.c | 73 +- .../ble-host/sources/stack/att/atts_ccc.c | 34 +- .../ble-host/sources/stack/att/atts_csf.c | 49 +- .../ble-host/sources/stack/att/atts_dyn.c | 34 +- .../ble-host/sources/stack/att/atts_eatt.c | 526 ++++++ .../ble-host/sources/stack/att/atts_ind.c | 236 +-- .../ble-host/sources/stack/att/atts_main.c | 159 +- .../ble-host/sources/stack/att/atts_main.h | 128 +- .../ble-host/sources/stack/att/atts_proc.c | 220 ++- .../ble-host/sources/stack/att/atts_read.c | 141 +- .../ble-host/sources/stack/att/atts_sign.c | 123 +- .../ble-host/sources/stack/att/atts_write.c | 78 +- .../ble-host/sources/stack/cfg/cfg_stack.c | 73 +- .../ble-host/sources/stack/cfg/cfg_stack.h | 74 +- .../stack/ble-host/sources/stack/dm/dm_adv.c | 38 +- .../stack/ble-host/sources/stack/dm/dm_adv.h | 41 +- .../ble-host/sources/stack/dm/dm_adv_ae.c | 147 +- .../ble-host/sources/stack/dm/dm_adv_leg.c | 34 +- .../ble-host/sources/stack/dm/dm_bis_master.c | 883 ++++++++++ .../ble-host/sources/stack/dm/dm_bis_slave.c | 905 +++++++++++ .../stack/ble-host/sources/stack/dm/dm_cis.c | 655 ++++++++ .../stack/ble-host/sources/stack/dm/dm_cis.h | 292 ++++ .../ble-host/sources/stack/dm/dm_cis_master.c | 943 +++++++++++ .../ble-host/sources/stack/dm/dm_cis_slave.c | 187 +++ .../ble-host/sources/stack/dm/dm_cis_sm.c | 263 +++ .../stack/ble-host/sources/stack/dm/dm_conn.c | 212 ++- .../stack/ble-host/sources/stack/dm/dm_conn.h | 118 +- .../ble-host/sources/stack/dm/dm_conn_cte.c | 91 +- .../sources/stack/dm/dm_conn_master.c | 51 +- .../sources/stack/dm/dm_conn_master_ae.c | 43 +- .../sources/stack/dm/dm_conn_master_leg.c | 43 +- .../ble-host/sources/stack/dm/dm_conn_slave.c | 51 +- .../sources/stack/dm/dm_conn_slave_ae.c | 43 +- .../sources/stack/dm/dm_conn_slave_leg.c | 43 +- .../ble-host/sources/stack/dm/dm_conn_sm.c | 69 +- .../stack/ble-host/sources/stack/dm/dm_dev.c | 36 +- .../stack/ble-host/sources/stack/dm/dm_dev.h | 34 +- .../ble-host/sources/stack/dm/dm_dev_priv.c | 46 +- .../stack/ble-host/sources/stack/dm/dm_iso.c | 889 ++++++++++ .../stack/ble-host/sources/stack/dm/dm_main.c | 89 +- .../stack/ble-host/sources/stack/dm/dm_main.h | 49 +- .../stack/ble-host/sources/stack/dm/dm_past.c | 40 +- .../stack/ble-host/sources/stack/dm/dm_phy.c | 40 +- .../stack/ble-host/sources/stack/dm/dm_phy.h | 34 +- .../stack/ble-host/sources/stack/dm/dm_priv.c | 83 +- .../stack/ble-host/sources/stack/dm/dm_priv.h | 60 +- .../stack/ble-host/sources/stack/dm/dm_scan.c | 34 +- .../stack/ble-host/sources/stack/dm/dm_scan.h | 40 +- .../ble-host/sources/stack/dm/dm_scan_ae.c | 34 +- .../ble-host/sources/stack/dm/dm_scan_leg.c | 34 +- .../stack/ble-host/sources/stack/dm/dm_sec.c | 35 +- .../stack/ble-host/sources/stack/dm/dm_sec.h | 34 +- .../ble-host/sources/stack/dm/dm_sec_lesc.c | 34 +- .../ble-host/sources/stack/dm/dm_sec_master.c | 34 +- .../ble-host/sources/stack/dm/dm_sec_slave.c | 34 +- .../ble-host/sources/stack/dm/dm_sync_ae.c | 97 +- .../ble-host/sources/stack/hci/hci_main.c | 52 +- .../ble-host/sources/stack/hci/hci_main.h | 36 +- .../ble-host/sources/stack/l2c/l2c_coc.c | 1079 ++++++++++++- .../ble-host/sources/stack/l2c/l2c_main.c | 34 +- .../ble-host/sources/stack/l2c/l2c_main.h | 34 +- .../ble-host/sources/stack/l2c/l2c_master.c | 34 +- .../ble-host/sources/stack/l2c/l2c_slave.c | 82 +- .../ble-host/sources/stack/smp/smp_act.c | 64 +- .../stack/ble-host/sources/stack/smp/smp_db.c | 34 +- .../ble-host/sources/stack/smp/smp_main.c | 37 +- .../ble-host/sources/stack/smp/smp_main.h | 36 +- .../ble-host/sources/stack/smp/smp_non.c | 34 +- .../ble-host/sources/stack/smp/smp_sc_act.c | 36 +- .../ble-host/sources/stack/smp/smp_sc_main.c | 37 +- .../ble-host/sources/stack/smp/smp_sc_main.h | 34 +- .../ble-host/sources/stack/smp/smpi_act.c | 35 +- .../ble-host/sources/stack/smp/smpi_main.h | 34 +- .../ble-host/sources/stack/smp/smpi_sc_act.c | 37 +- .../ble-host/sources/stack/smp/smpi_sc_sm.c | 34 +- .../ble-host/sources/stack/smp/smpi_sm.c | 34 +- .../ble-host/sources/stack/smp/smpr_act.c | 35 +- .../ble-host/sources/stack/smp/smpr_main.h | 34 +- .../ble-host/sources/stack/smp/smpr_sc_act.c | 37 +- .../ble-host/sources/stack/smp/smpr_sc_sm.c | 38 +- .../ble-host/sources/stack/smp/smpr_sm.c | 38 +- .../stack/platform/include/pal_audio_amp.h | 66 - .../stack/platform/include/pal_bb.h | 82 +- .../stack/platform/include/pal_bb_154.h | 661 ++++++++ .../stack/platform/include/pal_bb_ble.h | 135 +- .../platform/include/pal_bb_ble_tester.h | 57 +- .../stack/platform/include/pal_btn.h | 72 +- .../stack/platform/include/pal_cfg.h | 38 +- .../stack/platform/include/pal_codec.h | 123 ++ .../stack/platform/include/pal_crypto.h | 47 +- .../stack/platform/include/pal_flash.h | 78 + .../stack/platform/include/pal_i2s.h | 102 ++ .../stack/platform/include/pal_io_exp.h | 36 +- .../stack/platform/include/pal_led.h | 48 +- .../stack/platform/include/pal_nvm.h | 83 - .../stack/platform/include/pal_radio.h | 69 +- .../stack/platform/include/pal_radio2.h | 115 ++ .../stack/platform/include/pal_rtc.h | 61 +- .../stack/platform/include/pal_spi.h | 86 + .../stack/platform/include/pal_sys.h | 66 +- .../stack/platform/include/pal_timer.h | 46 +- .../stack/platform/include/pal_twi.h | 39 +- .../stack/platform/include/pal_types.h | 66 +- .../stack/platform/include/pal_uart.h | 45 +- .../stack/wsf/include/hci_defs.h | 1425 ++++++++++------- .../TARGET_CORDIO/stack/wsf/include/ll_defs.h | 592 +++++++ .../stack/wsf/include/util/bda.h | 36 +- .../stack/wsf/include/util/bstream.h | 38 +- .../stack/wsf/include/util/calc128.h | 40 +- .../stack/wsf/include/util/crc32.h | 36 +- .../stack/wsf/include/util/fcs.h | 34 +- .../stack/wsf/include/util/prand.h | 39 +- .../stack/wsf/include/util/print.h | 36 +- .../stack/wsf/include/util/terminal.h | 56 +- .../stack/wsf/include/util/wstr.h | 40 +- .../stack/wsf/include/wsf_assert.h | 42 +- .../TARGET_CORDIO/stack/wsf/include/wsf_buf.h | 46 +- .../stack/wsf/include/wsf_bufio.h | 38 +- .../TARGET_CORDIO/stack/wsf/include/wsf_cs.h | 38 +- .../stack/wsf/include/wsf_detoken.h | 38 +- .../TARGET_CORDIO/stack/wsf/include/wsf_efs.h | 48 +- .../stack/wsf/include/wsf_heap.h | 36 +- .../stack/wsf/include/wsf_math.h | 34 +- .../TARGET_CORDIO/stack/wsf/include/wsf_msg.h | 55 +- .../TARGET_CORDIO/stack/wsf/include/wsf_nvm.h | 75 +- .../TARGET_CORDIO/stack/wsf/include/wsf_os.h | 68 +- .../stack/wsf/include/wsf_queue.h | 42 +- .../stack/wsf/include/wsf_timer.h | 63 +- .../stack/wsf/include/wsf_trace.h | 130 +- .../stack/wsf/include/wsf_types.h | 91 +- .../wsf/sources/port/baremetal/wsf_assert.c | 39 +- .../wsf/sources/port/baremetal/wsf_buf.c | 55 +- .../wsf/sources/port/baremetal/wsf_bufio.c | 49 +- .../wsf/sources/port/baremetal/wsf_detoken.c | 44 +- .../wsf/sources/port/baremetal/wsf_efs.c | 45 +- .../wsf/sources/port/baremetal/wsf_heap.c | 48 +- .../wsf/sources/port/baremetal/wsf_msg.c | 75 +- .../wsf/sources/port/baremetal/wsf_nvm.c | 214 ++- .../wsf/sources/port/baremetal/wsf_os_int.h | 86 - .../wsf/sources/port/baremetal/wsf_queue.c | 41 +- .../wsf/sources/port/baremetal/wsf_timer.c | 157 +- .../wsf/sources/port/baremetal/wsf_trace.c | 51 +- .../stack/wsf/sources/util/bda.c | 36 +- .../stack/wsf/sources/util/bstream.c | 38 +- .../stack/wsf/sources/util/calc128.c | 40 +- .../stack/wsf/sources/util/crc32.c | 36 +- .../stack/wsf/sources/util/fcs.c | 34 +- .../stack/wsf/sources/util/prand.c | 42 +- .../stack/wsf/sources/util/print.c | 34 +- .../stack/wsf/sources/util/terminal.c | 59 +- .../stack/wsf/sources/util/wstr.c | 40 +- .../TARGET_CORDIO/stack_adaptation/hci_tr.c | 283 +--- .../TARGET_CORDIO/stack_adaptation/hci_vs.c | 301 +++- .../TARGET_CORDIO/stack_adaptation/wsf_cs.c | 111 +- .../TARGET_CORDIO/stack_adaptation/wsf_os.c | 170 +- 212 files changed, 21182 insertions(+), 5717 deletions(-) create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/eatt_api.h delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_bis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes_rev.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/pal/sec_ccm.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_eatt.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_eatt.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_sm.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_iso.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_audio_amp.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_154.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_codec.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_flash.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_i2s.h delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_nvm.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio2.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_spi.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_os_int.h diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h index e0309e0e687..fd285de1828 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Attribute protocol client and server API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Attribute protocol client and server API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_API_H @@ -107,16 +109,21 @@ enum /*!< \brief Internal note: event val ATTC_EXECUTE_WRITE_RSP, /*!< \brief Execute write response */ ATTC_HANDLE_VALUE_NTF, /*!< \brief Handle value notification */ ATTC_HANDLE_VALUE_IND, /*!< \brief Handle value indication */ + ATTC_READ_MULT_VAR_RSP = 16, /*!< \brief Read multiple variable length response */ + ATTC_MULT_VALUE_NTF, /*!< \brief Read multiple value notification */ /* ATT server callback events */ ATTS_HANDLE_VALUE_CNF, /*!< \brief Handle value confirmation */ + ATTS_MULT_VALUE_CNF, /*!< \brief Handle multiple value confirmation */ ATTS_CCC_STATE_IND, /*!< \brief Client chracteristic configuration state change */ ATTS_DB_HASH_CALC_CMPL_IND, /*!< \brief Database hash calculation complete */ /* ATT common callback events */ - ATT_MTU_UPDATE_IND /*!< \brief Negotiated MTU value */ + ATT_MTU_UPDATE_IND, /*!< \brief Negotiated MTU value */ + ATT_EATT_CONN_CMPL_IND, /*!< \brief EATT Connect channels complete */ + ATT_EATT_RECONFIG_CMPL_IND /*!< \brief EATT Reconfigure complete */ }; /*! \brief ATT callback events */ -#define ATT_CBACK_END ATT_MTU_UPDATE_IND /*!< \brief ATT callback event ending value */ +#define ATT_CBACK_END ATT_EATT_RECONFIG_CMPL_IND /*!< \brief ATT callback event ending value */ /**@}*/ /** \name ATT Client Awareness of Database Change @@ -146,6 +153,18 @@ typedef struct uint8_t numPrepWrites; /*!< \brief number of queued prepare writes supported by server */ } attCfg_t; +/*! \brief EATT run-time configurable parameters */ +typedef struct +{ + uint16_t mtu; /*!< \brief MTU */ + uint16_t mps; /*!< \brief MPS */ + bool_t initiateEatt; /*!< \brief Open EATT channels automatically on connect */ + uint8_t authoriz; /*!< \brief Authorization required */ + uint8_t secLevel; /*!< \brief Security level required */ + uint8_t numChans; /*!< \brief Number of enhanced l2cap channels per connection */ + uint8_t *pPriorityTbl; /*!< \brief Min priority required for each channel */ +} eattCfg_t; + /*! * \brief ATT callback event * @@ -386,6 +405,9 @@ typedef void (*attsCccCback_t)(attsCccEvt_t *pEvt); /**@{*/ /*! \brief Configuration pointer */ extern attCfg_t *pAttCfg; + +/*! \brief Enhanced configuration pointer */ +extern eattCfg_t *pEattCfg; /**@}*/ /*! \} */ /* STACK_INIT */ @@ -771,12 +793,11 @@ void AttsContinueWriteReq(dmConnId_t connId, uint16_t handle, uint8_t status); * * \param connId DM connection ID. * \param pCsrk Pointer to data signing key (CSRK). - * \param authenticated True if CSRK is authenticated and false otherwise. * * \return None. */ /*************************************************************************************************/ -void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk, bool_t authenticated); +void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk); /*************************************************************************************************/ /*! @@ -865,10 +886,10 @@ void AttsCsfGetFeatures(dmConnId_t connId, uint8_t *pCsfOut, uint8_t pCsfOutLen) * * \param connId DM connection ID. * - * \return Client's change-aware state. + * \return Client's change-aware state. See ::attClientAwareStates. */ /*************************************************************************************************/ -uint8_t AttsCsfGetChangeAwareState(dmConnId_t connId); +uint8_t AttsCsfGetClientChangeAwareState(dmConnId_t connId); /*************************************************************************************************/ /*! @@ -884,7 +905,7 @@ uint8_t AttsCsfGetChangeAwareState(dmConnId_t connId); * application) will have updated all persistent records prior to calling this function. */ /*************************************************************************************************/ -void AttsCsfSetClientsChangeAwarenessState(dmConnId_t connId, uint8_t state); +void AttsCsfSetClientChangeAwareState(dmConnId_t connId, uint8_t state); /*************************************************************************************************/ /*! @@ -1273,6 +1294,36 @@ void AttcDiscCharStart(dmConnId_t connId, attcDiscCb_t *pCb); /*************************************************************************************************/ uint8_t AttcDiscCharCmpl(attcDiscCb_t *pCb, attEvt_t *pMsg); +/*************************************************************************************************/ +/*! + * \brief This utility function starts service include discovery for a service on a peer device. + * The service must have been previously discovered by calling AttcDiscService() and +* AttcDiscServiceCmpl(). + * + * \param connId DM connection ID. + * \param pCb Pointer to service discovery control block. + * + * \return None. + */ +/*************************************************************************************************/ +void AttcDiscIncSvcStart(dmConnId_t connId, attcDiscCb_t *pCb); + +/*************************************************************************************************/ +/*! + * \brief This utility function processes a service include discovery result. It should be + * called when an ATTC_READ_BY_TYPE_RSP allback event is received after service include + * discovery is initiated by calling AttcDiscIncSvcStart(). + * + * \param pCb Pointer to service discovery control block. + * \param pMsg ATT callback event message. + * + * \return ATT_CONTINUING if successful and discovery procedure is continuing. + * ATT_SUCCESS if discovery procedure completed successfully. + * Otherwise the discovery procedure failed. + */ +/*************************************************************************************************/ +uint8_t AttcDiscIncSvcCmpl(attcDiscCb_t *pCb, attEvt_t *pMsg); + /*************************************************************************************************/ /*! * \brief This utility function starts characteristic configuration for characteristics on a @@ -1321,12 +1372,17 @@ uint8_t AttcDiscConfigResume(dmConnId_t connId, attcDiscCb_t *pCb); /*************************************************************************************************/ /*! - * \brief For internal use only. + * \brief Initiate an attribute protocol Exchange MTU Request. * * \param connId DM connection ID. * \param mtu Attribute protocol MTU. * * \return None. + * + * \note The Exchange MTU Request will be initiated automatically on a master connection. + * + * \note This API can be used by the application to initiate an Exchange MTU Request on slave + * connections. */ /*************************************************************************************************/ void AttcMtuReq(dmConnId_t connId, uint16_t mtu); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_defs.h index 90baa88bdbf..8fea47d94f7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_defs.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_defs.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Attribute protocol constants and definitions from the Bluetooth specification. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Attribute protocol constants and definitions from the Bluetooth specification. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_DEFS_H @@ -101,8 +103,9 @@ extern "C" { #define ATT_ERR_UNDEFINED 0x75 /*!< \brief Other undefined error */ #define ATT_ERR_REQ_NOT_FOUND 0x76 /*!< \brief Required characteristic not found */ #define ATT_ERR_MTU_EXCEEDED 0x77 /*!< \brief Attribute PDU length exceeded MTU size */ -#define ATT_CONTINUING 0x78 /*!< \brief Procedure continuing */ -#define ATT_RSP_PENDING 0x79 /*!< \brief Responsed delayed pending higher layer */ +#define ATT_ERR_NO_CHANNEL 0x78 /*!< \brief No enhanced channel available */ +#define ATT_CONTINUING 0x79 /*!< \brief Procedure continuing */ +#define ATT_RSP_PENDING 0x7A /*!< \brief Response delayed pending higher layer */ /**@}*/ /** \name ATT Application Error Codes @@ -110,6 +113,10 @@ extern "C" { */ /**@{*/ #define ATT_ERR_VALUE_RANGE 0x80 /*!< \brief Value out of range */ +#define ATT_ERR_INVALID_CHANGE_CTR 0x80 /*!< \brief Invalid change counter */ +#define ATT_ERR_OPCODE_NOT_SUPPORTED 0x81 /*!< \brief Opcode out of range */ +#define ATT_ERR_MUTE_DISABLE 0x82 /*!< \brief Mute disable */ +#define ATT_ERR_VALUE_RANGE_x83 0x83 /*!< \brief Value out of range 0x83 */ /**@}*/ /** \name ATT HCI Error Status @@ -156,7 +163,9 @@ extern "C" { #define ATT_PDU_VALUE_NTF 0x1B /*!< \brief Handle value notification */ #define ATT_PDU_VALUE_IND 0x1D /*!< \brief Handle value indication */ #define ATT_PDU_VALUE_CNF 0x1E /*!< \brief Handle value confirmation */ -#define ATT_PDU_MAX 0x1F /*!< \brief PDU Maximum */ +#define ATT_PDU_READ_MULT_VAR_REQ 0x20 /*!< \brief Read multiple variable length request */ +#define ATT_PDU_READ_MULT_VAR_RSP 0x21 /*!< \brief Read multiple variable length response */ +#define ATT_PDU_MULT_VALUE_NTF 0x23 /*!< \brief Handle value multiple notification */ /**@}*/ /** \name ATT PDU Length Fields @@ -191,6 +200,9 @@ extern "C" { #define ATT_VALUE_NTF_LEN 3 /*!< \brief Value notification length. */ #define ATT_VALUE_IND_LEN 3 /*!< \brief Value indication length. */ #define ATT_VALUE_CNF_LEN 1 /*!< \brief Value confirmation length. */ +#define ATT_READ_MULT_VAR_REQ_LEN 1 /*!< \brief Base read multiple variable request length. */ +#define ATT_READ_MULT_VAR_RSP_LEN 1 /*!< \brief Base read multiple variable response length. */ +#define ATT_PDU_MULT_VALUE_NTF_LEN 1 /*!< \brief Base multiple variable notification length. */ /**@}*/ /** \name ATT Find Information Response Format @@ -317,12 +329,22 @@ extern "C" { * Flags of features supported by the GATT Client */ /**@{*/ -#define ATTS_CSF_ROBUST_CACHING 1 /*!< \brief Robust caching. */ -#define ATTS_CSF_OCT0_FEATURES ATTS_CSF_ROBUST_CACHING /*!< \brief Mask of all client supported features. */ +#define ATTS_CSF_ROBUST_CACHING (1<<0) /*!< \brief Robust caching. */ +#define ATTS_CSF_EATT_BEARER (1<<1) /*!< \brief Enhanced ATT Bearer. */ +#define ATTS_CSF_MULTI_VAL_NTF (1<<2) /*!< \brief Multiple Handle Value Notifications. */ + +#define ATTS_CSF_ALL_FEATURES (0x7) /*!< \brief Mask of all client supported features. */ #define ATT_CSF_LEN 1 /*!< \brief Length of client supported features array. */ /**@}*/ +/** \name GATT Server Supported Features +* Flags of features supported by the GATT Server +*/ +/**@{*/ +#define ATTS_SSF_EATT (1<<0) /*!< \brief Enhanced ATT supported. */ +/**@}*/ + /*! \} */ /* STACK_ATT_API */ #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_handler.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_handler.h index edb2add9b32..11765a3a98d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_handler.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_handler.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Interface to ATT event handler. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Interface to ATT event handler. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_HANDLER_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_uuid.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_uuid.h index b51cabdf902..5896a1c9bae 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_uuid.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_uuid.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Attribute protocol UUIDs from the Bluetooth specification. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Attribute protocol UUIDs from the Bluetooth specification. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_UUID_H @@ -207,6 +209,7 @@ extern "C" { #define ATT_UUID_MESH_PROXY_DATA_OUT 0x2ADE /*!< \brief Mesh Proxy Data Out */ #define ATT_UUID_CLIENT_SUPPORTED_FEATURES 0x2B29 /*!< \brief Client Supported Features */ #define ATT_UUID_DATABASE_HASH 0x2B2A /*!< \brief Database Hash */ +#define ATT_UUID_SERVER_SUPPORTED_FEATURES 0x2B3A /*!< \brief Server Supported Features */ #define ATT_UUID_CTE_ENABLE 0x7F80 /*!< \brief Constant Tone Extension enable */ #define ATT_UUID_CTE_MIN_LEN 0x7F81 /*!< \brief Constant Tone Extension minimum length */ #define ATT_UUID_CTE_TX_CNT 0x7F82 /*!< \brief Constant Tone Extension transmit count */ @@ -387,6 +390,9 @@ extern const uint8_t attPlxsSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Pulse Oxime extern const uint8_t attUdsSvcUuid[ATT_16_UUID_LEN]; /*!< \brief User Data Service */ extern const uint8_t attMprvSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Provisioning Service */ extern const uint8_t attMprxSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Proxy Service */ +extern const uint8_t attWssSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Weight scale service */ +extern const uint8_t attCteSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension service */ + /**@}*/ /** \name GATT UUID Variables @@ -519,18 +525,18 @@ extern const uint8_t attMprvDinChUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Provis extern const uint8_t attMprvDoutChUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Provisioning Data Out */ extern const uint8_t attMprxDinChUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Proxy Data In */ extern const uint8_t attMprxDoutChUuid[ATT_16_UUID_LEN]; /*!< \brief Mesh Proxy Data Out */ -extern const uint8_t attWssSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Weight scale service */ extern const uint8_t attWmChUuid[ATT_16_UUID_LEN]; /*!< \brief Weight measurement */ extern const uint8_t attWsfChUuid[ATT_16_UUID_LEN]; /*!< \brief Weight scale feature */ extern const uint8_t attGattCsfChUuid[ATT_16_UUID_LEN]; /*!< \brief Client supported features */ extern const uint8_t attGattDbhChUuid[ATT_16_UUID_LEN]; /*!< \brief Database hash */ -extern const uint8_t attCteSvcUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension service */ extern const uint8_t attCteEnChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension enable */ extern const uint8_t attCteMinLenChUuid[ATT_16_UUID_LEN];/*!< \brief Constant Tone Extension minimum length */ extern const uint8_t attCteTxCntChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension minimum transmit count */ extern const uint8_t attCteTxDurChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension transmit duration */ extern const uint8_t attCteIntChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension interval */ extern const uint8_t attCtePhyChUuid[ATT_16_UUID_LEN]; /*!< \brief Constant Tone Extension PHY */ +extern const uint8_t attSsfChUuid[ATT_16_UUID_LEN]; /*!< \brief Server supported features */ + /**@}*/ /*! \} */ /* STACK_ATT_API */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h index 0c1e4c9727a..daadd5d91fc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device Manager subsystem API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device Manager subsystem API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_API_H @@ -135,6 +137,12 @@ extern "C" { /*! \brief Unknown sync ID or other error */ #define DM_SYNC_ID_NONE 0 + +/*! \brief Unknown Connected Isochronous Group (CIG) ID or other error */ +#define DM_CIG_ID_NONE 0xFF + +/*! \brief Unknown Connected Isochronous Stream (CIS) ID or other error */ +#define DM_CIS_ID_NONE 0xFF /**@}*/ /** \name GAP Address Type @@ -182,6 +190,16 @@ extern "C" { #define DM_ADV_TYPE_LESC_CONFIRM 0x22 /*!< \brief LE Secure Connections confirm value */ #define DM_ADV_TYPE_LESC_RANDOM 0x23 /*!< \brief LE Secure Connections random value */ #define DM_ADV_TYPE_URI 0x24 /*!< \brief URI */ +#define DM_ADV_TYPE_INDOOR_POS 0x25 /*!< \brief Indoor positioning service */ +#define DM_ADV_TYPE_TRANS_DISC 0x26 /*!< \brief Transport discovery service */ +#define DM_ADV_TYPE_LE_SUP_FEAT 0x27 /*!< \brief LE supported features */ +#define DM_ADV_TYPE_CH_MAP_UPD_IND 0x28 /*!< \brief Channel map update indication */ +#define DM_ADV_TYPE_PB_ADV 0x29 /*!< \brief PB-ADV */ +#define DM_ADV_TYPE_MESH_MSG 0x2A /*!< \brief Mesh message */ +#define DM_ADV_TYPE_MESH_BEACON 0x2B /*!< \brief Mesh beacon*/ +#define DM_ADV_TYPE_BIG_INFO 0x2C /*!< \brief BIG Info */ +#define DM_ADV_TYPE_BCAST_CODE 0x2D /*!< \brief Mesh beacon */ +#define DM_ADV_TYPE_3D_INFO_DATA 0x3D /*!< \brief 3D information data */ #define DM_ADV_TYPE_MANUFACTURER 0xFF /*!< \brief Manufacturer specific data */ /**@}*/ @@ -345,6 +363,15 @@ extern "C" { #define DM_SEC_LEVEL_ENC_LESC 3 /*!< \brief Connection is encrypted with LE Secure Connections */ /**@}*/ +/** \name GAP Broadcast Security Level +* GAP Mode 3 Security Levels +*/ +/**@{*/ +#define DM_SEC_LEVEL_BCAST_NONE 0 /*!< \brief No security (no authentication and no encryption) */ +#define DM_SEC_LEVEL_BCAST_UNAUTH 1 /*!< \brief Use of unauthenticated Broadcast_Code */ +#define DM_SEC_LEVEL_BCAST_AUTH 2 /*!< \brief Use of authenticated Broadcast_Code */ +/**@}*/ + /** \name GAP Random Address Types * Random address type masks. */ @@ -422,6 +449,21 @@ extern "C" { #define DM_ERR_L2C_RX_PDU_LEN_EXCEEDED 0x03 /*!< \brief Registered COC MPS exceeded maximum RX PDU length */ /**@}*/ +/** \name DM Conn CTE states + * Internal states of the DM conn CTE. + */ +/**@{*/ +enum +{ + DM_CONN_CTE_STATE_IDLE, /*!< Idle */ + DM_CONN_CTE_STATE_INITIATING, /*!< Initiating CTE request */ + DM_CONN_CTE_STATE_RESPONDING, /*!< Responding to CTE request */ + DM_CONN_CTE_STATE_SAMPLING, /*!< Sampling received CTE */ + DM_CONN_CTE_STATE_STARTING, /*!< Starting CTE request, CTE response or sampling received CTE */ + DM_CONN_CTE_STATE_STOPPING, /*!< Stopping CTE request, CTE response or sampling received CTE */ +}; +/**@}*/ + /** \name DM Legacy Advertising Handle * Default handle for legacy advertising when using legacy HCI interface. In this case only one advertising * set is allowed so all activity uses the same handle. @@ -507,6 +549,25 @@ enum DM_CONN_CTE_RSP_START_IND, /*!< \brief Responding to connection CTE request started */ DM_CONN_CTE_RSP_STOP_IND, /*!< \brief Responding to connection CTE request stopped */ DM_READ_ANTENNA_INFO_IND, /*!< \brief Antenna information read */ + DM_CIS_CIG_CONFIG_IND, /*!< \brief CIS CIG configure complete */ + DM_CIS_CIG_REMOVE_IND, /*!< \brief CIS CIG remove complete */ + DM_CIS_REQ_IND, /*!< \brief CIS request */ + DM_CIS_OPEN_IND, /*!< \brief CIS connection opened */ + DM_CIS_CLOSE_IND, /*!< \brief CIS connection closed */ + DM_REQ_PEER_SCA_IND, /*!< \brief Request peer SCA complete */ + DM_ISO_DATA_PATH_SETUP_IND, /*!< \brief ISO data path setup complete */ + DM_ISO_DATA_PATH_REMOVE_IND, /*!< \brief ISO data path remove complete */ + DM_DATA_PATH_CONFIG_IND, /*!< \brief Data path configure complete */ + DM_READ_LOCAL_SUP_CODECS_IND, /*!< \brief Local supported codecs read */ + DM_READ_LOCAL_SUP_CODEC_CAP_IND, /*!< \brief Local supported codec capabilities read */ + DM_READ_LOCAL_SUP_CTR_DLY_IND, /*!< \brief Local supported controller delay read */ + DM_BIG_START_IND, /*!< \brief BIG started */ + DM_BIG_STOP_IND, /*!< \brief BIG stopped */ + DM_BIG_SYNC_EST_IND, /*!< \brief BIG sync established */ + DM_BIG_SYNC_EST_FAIL_IND, /*!< \brief BIG sync establishment failed */ + DM_BIG_SYNC_LOST_IND, /*!< \brief BIG sync lost */ + DM_BIG_SYNC_STOP_IND, /*!< \brief BIG sync stopped */ + DM_BIG_INFO_ADV_REPORT_IND, /*!< \brief BIG Info advertising data received from peer device */ DM_L2C_CMD_REJ_IND, /*!< \brief L2CAP Command Reject */ DM_ERROR_IND, /*!< \brief General error */ DM_HW_ERROR_IND, /*!< \brief Hardware error */ @@ -766,9 +827,28 @@ typedef union hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStart; /*!< \brief handles \ref DM_CONN_CTE_RSP_START_IND */ hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStop; /*!< \brief handles \ref DM_CONN_CTE_RSP_STOP_IND */ hciLeReadAntennaInfoCmdCmplEvt_t readAntennaInfo; /*!< \brief handles \ref DM_READ_ANTENNA_INFO_IND */ -#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + hciLeSetCigParamsCmdCmplEvt_t cisCigConfig; /*!< \brief handles \ref DM_CIS_CIG_CONFIG_IND */ + hciLeRemoveCigCmdCmplEvt_t cisCigRemove; /*!< \brief handles \ref DM_CIS_CIG_REMOVE_IND */ + HciLeCisReqEvt_t cisReq; /*!< \brief handles \ref DM_CIS_REQ_IND */ + HciLeCisEstEvt_t cisOpen; /*!< \brief handles \ref DM_CIS_OPEN_IND */ + hciDisconnectCmplEvt_t cisClose; /*!< \brief handles \ref DM_CIS_CLOSE_IND */ + HciLeReqPeerScaCmplEvt_t_t reqPeerSca; /*!< \brief handles \ref DM_REQ_PEER_SCA_IND */ + hciLeSetupIsoDataPathCmdCmplEvt_t isoDataPathSetup; /*!< \brief handles \ref DM_ISO_DATA_PATH_SETUP_IND */ + hciLeRemoveIsoDataPathCmdCmplEvt_t isoDataPathRemove; /*!< \brief handles \ref DM_ISO_DATA_PATH_REMOVE_IND */ + hciConfigDataPathCmdCmplEvt_t dataPathConfig; /*!< \brief handles \ref DM_DATA_PATH_CONFIG_IND */ + hciReadLocalSupCodecsCmdCmplEvt_t readLocalSupCodecs; /*!< \brief handles \ref DM_READ_LOCAL_SUP_CODECS_IND */ + hciReadLocalSupCodecCapCmdCmplEvt_t readLocalSupCodecCap; /*!< \brief handles \ref DM_READ_LOCAL_SUP_CODEC_CAP_IND */ + hciReadLocalSupCtrDlyCmdCmplEvt_t readLocalSupCtrDly; /*!< \brief handles \ref DM_READ_LOCAL_SUP_CTR_DLY_IND */ + HciLeCreateBigCmplEvt_t bigStart; /*!< \brief handles \ref DM_BIG_START_IND */ + HciLeTerminateBigCmplEvt_t bigStop; /*!< \brief handles \ref DM_BIG_STOP_IND */ + HciLeBigSyncEstEvt_t bigSyncEst; /*!< \brief handles \ref DM_BIG_SYNC_EST_IND */ + HciLeBigSyncEstEvt_t bigSyncEstFail; /*!< \brief handles \ref DM_BIG_SYNC_EST_FAIL_IND */ + HciLeBigSyncLostEvt_t bigSyncLost; /*!< \brief handles \ref DM_BIG_SYNC_LOST_IND */ + HciLeBigTermSyncCmplEvt_t bigSyncStop; /*!< \brief handles \ref DM_BIG_SYNC_STOP_IND */ + HciLeBigInfoAdvRptEvt_t bigInfoAdvRpt; /*!< \brief handles \ref DM_BIG_INFO_ADV_REPORT_IND */ + #if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS hciUnhandledCmdCmplEvt_t unhandledCmdCmplEvt; -#endif + #endif dmL2cCmdRejEvt_t l2cCmdRej; /*!< \brief handles \ref DM_L2C_CMD_REJ_IND */ /* common header used by DM_ERROR_IND */ hciHwErrorEvt_t hwError; /*!< \brief handles \ref DM_HW_ERROR_IND */ @@ -1136,6 +1216,18 @@ void DmAdvScanReqNotifEnable(uint8_t advHandle, bool_t scanReqNotifEna); /*************************************************************************************************/ void DmAdvSetFragPref(uint8_t advHandle, uint8_t fragPref); +/*************************************************************************************************/ +/*! + * \brief Set advertising SID for the given advertising handle. + * + * \param advHandle Advertising handle. + * \param advSid Advertsing SID. + * + * \return None. + */ +/*************************************************************************************************/ +void DmAdvSetSid(uint8_t advHandle, uint8_t advSid); + /*************************************************************************************************/ /*! * \brief Set the advertising parameters for periodic advertising. @@ -1211,6 +1303,17 @@ void DmPerAdvSetInterval(uint8_t advHandle, uint16_t intervalMin, uint16_t inter /*************************************************************************************************/ void DmPerAdvIncTxPwr(uint8_t advHandle, bool_t incTxPwr); +/*************************************************************************************************/ +/*! + * \brief Get status of periodic advertising handle. + * + * \param advHandle Advertising handle. + * + * \return TRUE if periodic advertising is running on that handle. FALSE, otherwise. +*/ +/*************************************************************************************************/ +bool_t DmPerAdvEnabled(uint8_t advHandle); + /*************************************************************************************************/ /*! * \brief Get the maximum advertising data length supported by Controller for a given advertising @@ -1570,6 +1673,42 @@ dmSyncId_t DmSyncStart(uint8_t advSid, uint8_t advAddrType, const uint8_t *pAdvA /*************************************************************************************************/ void DmSyncStop(dmSyncId_t syncId); +/*************************************************************************************************/ +/*! + * \brief Set the encryption mode of the Broadcast Isochronous Group (BIG) corresponding to the + * periodic advertising train identified by the sync handle. + * + * \param syncHandle Synch handle. + * \param encrypt FALSE (Unencrypted) or FALSE (Encrypted). + * + * \return None. + */ +/*************************************************************************************************/ +void DmSyncSetEncrypt(uint16_t syncHandle, bool_t encrypt); + +/*************************************************************************************************/ +/*! + * \brief Get the encryption mode of the Broadcast Isochronous Group (BIG) corresponding to the + * periodic advertising train identified by the sync handle. + * + * \param syncHandle Synch handle. + * + * \return TRUE if sync encrypted. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t DmSyncEncrypted(uint16_t syncHandle); + +/*************************************************************************************************/ +/*! + * \brief Get status of sync identified by the handle. + * + * \param syncHandle Synch handle. + * + * \return TRUE if sync is enabled for that handle. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t DmSyncEnabled(uint16_t syncHandle); + /*************************************************************************************************/ /*! * \brief DM enable or disable initial periodic advertisement reporting. @@ -1581,6 +1720,99 @@ void DmSyncStop(dmSyncId_t syncId); /*************************************************************************************************/ void DmSyncInitialRptEnable(bool_t enable); +/*************************************************************************************************/ +/*! + * \brief Synchronize to a Broadcast Isochronous Group (BIG) described in the periodic + * advertising train specified by the sync handle. + * + * \param bigHandle BIG handle. + * \param syncHandle Periodic advertising train handle. + * \param mse Maximum number of subevents. + * \param bigSyncTimeout Synchronization timeout for the BIS, in the units of 10ms. + * \param numBis Total number of BISes in the BIG. + * \param pBis List of indices of BISes (in ascending order). + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncStart(uint8_t bigHandle, uint16_t syncHandle, uint8_t mse, uint16_t bigSyncTimeout, + uint8_t numBis, uint8_t *pBis); + +/*************************************************************************************************/ +/*! + * \brief Stop synchronizing or cancel the process of synchronizing to the Broadcast Isochronous + * Group (BIG) identified by the handle. + * + * \note The command also terminates the reception of BISes in the BIG specified in \ref + * DmBigSyncStart, destroys the associated connection handles of the BISes in the BIG + * and removes the data paths for all BISes in the BIG. + * + * \param bigHandle BIG handle. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncStop(uint8_t bigHandle); + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the BIS sync is in use. + * + * \param handle BIS connection handle. + * + * \return TRUE if the BIS sync is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmBisSyncInUse(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Set the Broadcast Code for the given Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param encrypt FALSE (Unencrypted) or TRUE (Encrypted). + * \param authen FALSE (Unauthenticated) or TRUE (Authenticated). + * \param pBcastCode Broadcast code. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncSetBcastCode(uint8_t bigHandle, bool_t encrypt, bool_t authen, uint8_t *pBcastCode); + +/*************************************************************************************************/ +/*! + * \brief Set the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG). + * + * \param bigHandle BIG handle. + * \param secLevel Security level. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncSetSecLevel(uint8_t bigHandle, uint8_t secLevel); + +/*************************************************************************************************/ +/*! + * \brief Get the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG) connection handle. + * + * \param handle BIS connection handle. + * + * \return Security level. + */ +/*************************************************************************************************/ +uint8_t DmBigSyncGetSecLevel(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Initialize DM BIS manager for operation as master. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBisMasterInit(void); + /*************************************************************************************************/ /*! * \brief Add device to periodic advertiser list. @@ -1785,6 +2017,28 @@ void DmConnCteRspStart(dmConnId_t connId); /*************************************************************************************************/ void DmConnCteRspStop(dmConnId_t connId); +/*************************************************************************************************/ +/*! + * \brief Returns the device manager's CTE request state for a given connection. + * + * \param connId Connection identifier. + * + * \return The CTE request state. + */ +/*************************************************************************************************/ +uint8_t DmConnCteGetReqState(dmConnId_t connId); + +/*************************************************************************************************/ +/*! + * \brief Returns the device manager's CTE response state for a given connection. + * + * \param connId Connection identifier. + * + * \return The CTE response state. + */ +/*************************************************************************************************/ +uint8_t DmConnCteGetRspState(dmConnId_t connId); + /*************************************************************************************************/ /*! * \brief Read the switching rates, the sampling rates, the number of antennae, and the maximum @@ -2078,6 +2332,407 @@ uint8_t DmConnRole(dmConnId_t connId); /*************************************************************************************************/ void DmWriteAuthPayloadTimeout(dmConnId_t connId, uint16_t timeout); +/*************************************************************************************************/ +/*! + * \brief Request the Sleep Clock Accuracy (SCA) of a peer device. + * + * \param connId Connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void DmConnRequestPeerSca(dmConnId_t connId); + +/**@}*/ + +/** \name DM CIS Functions +* Functions for forming and managing Connected Isochronous Stream (CIS) streams. +*/ +/**@{*/ + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisInit(void); + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager for operation as master. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisMasterInit(void); + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager for operation as slave. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisSlaveInit(void); + +/*************************************************************************************************/ +/*! + * \brief Set the interval, in microseconds, of periodic SDUs for the given Connected Isochronous + * Group (CIG). + * + * \param cigId CIG ID. + * \param sduIntervalMToS Time interval between start of consecutive SDUs from master Host. + * \param sduIntervalSToM Time interval between start of consecutive SDUs from slave Host. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetSduInterval(uint8_t cigId, uint32_t sduIntervalMToS, uint32_t sduIntervalSToM); + +/*************************************************************************************************/ +/*! + * \brief Set the slaves clock accuracy for the given Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * \param sca Slaves clck accuracy (0 if unknown). + * + * \return None. + * + * \note The slaves clock accuracy must which must be the worst-case sleep clock accuracy of the + * slaves that will participate in the CIG. + */ +/*************************************************************************************************/ +void DmCisCigSetSca(uint8_t cigId, uint8_t sca); + +/*************************************************************************************************/ +/*! + * \brief Set the packing scheme and framing format for the given Connected Isochronous Group + * (CIG). + * + * \param cigId CIG identifier. + * \param packing Packing scheme. + * \param framing Indicates format of CIS Data PDUs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetPackingFraming(uint8_t cigId, uint8_t packing, uint32_t framing); + +/*************************************************************************************************/ +/*! + * \brief Set the maximum transport latency, in microseconds, for the given Connected Isochronous + * Group (CIG). + * + * \param cigId CIG identifier. + * \param transLatMToS Maximum time for SDU to be transported from master Controller to slave Controller. + * \param transLatSToM Maximum time for SDU to be transported from slave Controller to master Controller. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetTransLatInterval(uint8_t cigId, uint16_t transLatMToS, uint16_t transLatSToM); + +/*************************************************************************************************/ +/*! + * \brief Set the parameters of one or more Connected Isochronous Streams (CISes) that are + * associated with the given Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * \param numCis Number of CIS to be configured. + * \param pCisParam CIS parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigConfig(uint8_t cigId, dmConnId_t numCis, HciCisCisParams_t *pCisParam); + +/*************************************************************************************************/ +/*! + * \brief Remove all the Connected Isochronous Streams (CISes) associated with the given + * Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigRemove(uint8_t cigId); + +/*************************************************************************************************/ +/*! + * \brief Create one or more Connected Isochronous Streams (CISes) using the connections + * identified by the ACL connection handles. + * + * \param numCis Total number of CISes to be created. + * \param pCisHandle List of connection handles of CISes. + * \param pAclHandle List of connection handles of ACLs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisOpen(uint8_t numCis, uint16_t *pCisHandle, uint16_t *pAclHandle); + +/*************************************************************************************************/ +/*! + * \brief Inform the Controller to accept the request for the Connected Isochronous Stream (CIS) + * that is identified by the connection handle. + * + * \param handle Connection handle of the CIS. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisAccept(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Inform the Controller to reject the request for the Connected Isochronous Stream (CIS) + * that is identified by the connection handle. + * + * \param handle Connection handle of the CIS to be rejected. + * \param reason Reason the CIS request was rejected. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisReject(uint16_t handle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief Close the Connected Isochronous Stream (CIS) connection with the given handle. + * + * \param handle CIS connection handle. + * \param reason Reason connection is being closed. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisClose(uint16_t handle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the Connected Isochronous Stream (CIS) + * connection is in use. + * + * \param handle CIS connection handle. + * + * \return TRUE if the CIS connection is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmCisConnInUse(uint16_t handle); + +/**@}*/ + +/** \name DM BIS Functions +* Functions for forming and managing Broadcast Isochronous Stream (BIS) streams and synchronization. +*/ +/**@{*/ + +/*************************************************************************************************/ +/*! + * \brief Initialize DM BIS manager for operation as slave. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBisSlaveInit(void); + +/*************************************************************************************************/ +/*! + * \brief Start a Broadcast Isochronous Group (BIG) with one or more Broadcast Isochronous + * Streams (BISes). + * + * \param bigHandle CIG identifier. + * \param advHandle Used to identify the periodic advertising train. + * \param numBis; Total number of BISes in the BIG. + * \param sduInterUsec Interval, in microseconds, of BIG SDUs. + * \param maxSdu Maximum size of SDU + * \param mtlMs Maximum time, in milliseconds, for transmitting SDU. + * \param rtn Retransmitted number. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigStart(uint8_t bigHandle, uint8_t advHandle, uint8_t numBis, uint32_t sduInterUsec, + uint16_t maxSdu, uint16_t mtlMs, uint8_t rtn); + +/*************************************************************************************************/ +/*! + * \brief Stop a Broadcast Isochronous Group (BIG) identified for the given handle. + * + * \param bigHandle BIG identifier. + * \param reason Reason BIG is terminated. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigStop(uint8_t bigHandle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the BIS is in use. + * + * \param handle BIS connection handle. + * + * \return TRUE if the BIS connection is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmBisInUse(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Set the PHYs used for transmission of PDUs of Broadcast Isochronous Streams (BISes) in + * Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param phyBits PHY bit field. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetPhy(uint8_t bigHandle, uint8_t phyBits); + +/*************************************************************************************************/ +/*! + * \brief Set the packing scheme and framing format for the given Broadcast Isochronous Group + * (BIG). + * + * \param bigHandle BIG handle. + * \param packing Packing scheme. + * \param framing Indicates format of BIS Data PDUs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetPackingFraming(uint8_t bigHandle, uint8_t packing, uint32_t framing); + +/*************************************************************************************************/ +/*! + * \brief Set the Broadcast Code for the given Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param encrypt FALSE (Unencrypted) or TRUE (Encrypted). + * \param authen FALSE (Unauthenticated) or TRUE (Authenticated). + * \param pBcastCode Broadcast code. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetBcastCode(uint8_t bigHandle, bool_t encrypt, bool_t authen, uint8_t *pBcastCode); + +/*************************************************************************************************/ +/*! + * \brief Set the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG). + * + * \param bigHandle BIG handle. + * \param secLevel Security level. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetSecLevel(uint8_t bigHandle, uint8_t secLevel); + +/*************************************************************************************************/ +/*! + * \brief Get the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG) connection handle. + * + * \param handle BIS connection handle. + * + * \return Security level. + */ +/*************************************************************************************************/ +uint8_t DmBigGetSecLevel(uint16_t handle); + +/** \name DM Isochronous (ISO) Functions +* Functions for setting up and managing isochronous data path between the Host and the Controller. +*/ +/**@{*/ +/*************************************************************************************************/ +/*! + * \brief Initialize DM ISO manager. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoInit(void); + +/*************************************************************************************************/ +/*! + * \brief Setup the isochronous data path between the Host and the Controller for an established + * Connected Isochronous Stream (CIS) or Broadcast Isochronous Stream (BIS) identified by + * the connection handle parameter. + * + * \param pDataPathParam Parameters to setup ISO data path. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoDataPathSetup(HciIsoSetupDataPath_t *pDataPathParam); + +/*************************************************************************************************/ +/*! + * \brief Remove the input and/or output data path(s) associated with a Connected Isochronous + * Stream (CIS) or Broadcast Isochronous Stream (BIS) identified by the connection handle + * parameter. + * + * \param handle Connection handle of CIS or BIS. + * \param directionBits Data path direction bits. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoDataPathRemove(uint16_t handle, uint8_t directionBits); + +/*************************************************************************************************/ +/*! + * \brief Request the Controller to configure the data transport path in a given direction + * between the Controller and the Host. + * + * \param pDataPathParam Parameters for configuring data path. + * + * \return None. + */ +/*************************************************************************************************/ +void DmDataPathConfig(HciConfigDataPath_t *pDataPathParam); + +/*************************************************************************************************/ +/*! + * \brief Read a list of the codecs supported by the Controller, as well as vendor specific + * codecs, which are defined by an individual manufacturer. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCodecs(void); + +/*************************************************************************************************/ +/*! + * \brief Read a list of codec capabilities supported by the Controller for a given codec. + * + * \param pCodecParam Parameters for reading local supported codec capabilities. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCodecCap(HciReadLocalSupCodecCaps_t *pCodecParam); + +/*************************************************************************************************/ +/*! + * \brief Read the range of supported Controller delays for the codec specified by Codec ID on + * a given transport type specified by Logical Transport Type, in the direction specified + * by Direction, and with the codec configuration specified by Codec Configuration. + * + * \param pDelayParam Parameters for reading local supported controller delay. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCtrDly(HciReadLocalSupControllerDly_t *pDelayParam); + /**@}*/ /** \name DM PHY Control Functions @@ -2127,10 +2782,10 @@ void DmSetPhy(dmConnId_t connId, uint8_t allPhys, uint8_t txPhys, uint8_t rxPhys /*************************************************************************************************/ /*! -* \brief Initialize DM PHY. -* -* \return None. -*/ + * \brief Initialize DM PHY. + * + * \return None. + */ /*************************************************************************************************/ void DmPhyInit(void); @@ -2273,7 +2928,7 @@ void DmSecLescInit(void); * \return None. */ /*************************************************************************************************/ -void DmSecPairReq(dmConnId_t connId, bool_t oob, uint8_t auth, uint8_t iKeyDist, uint8_t rKeyDist); +void DmSecPairReq(dmConnId_t connId, uint8_t oob, uint8_t auth, uint8_t iKeyDist, uint8_t rKeyDist); /*************************************************************************************************/ /*! @@ -2289,7 +2944,7 @@ void DmSecPairReq(dmConnId_t connId, bool_t oob, uint8_t auth, uint8_t iKeyDist, * \return None. */ /*************************************************************************************************/ -void DmSecPairRsp(dmConnId_t connId, bool_t oob, uint8_t auth, uint8_t iKeyDist, uint8_t rKeyDist); +void DmSecPairRsp(dmConnId_t connId, uint8_t oob, uint8_t auth, uint8_t iKeyDist, uint8_t rKeyDist); /*************************************************************************************************/ /*! @@ -2617,23 +3272,23 @@ uint8_t *DmConnLocalAddr(dmConnId_t connId); /*************************************************************************************************/ /*! -* \brief For internal use only. Return the peer resolvable private address (RPA). -* -* \param connId Connection ID. -* -* \return Pointer to peer RPA. -*/ + * \brief For internal use only. Return the peer resolvable private address (RPA). + * + * \param connId Connection ID. + * + * \return Pointer to peer RPA. + */ /*************************************************************************************************/ uint8_t *DmConnPeerRpa(dmConnId_t connId); /*************************************************************************************************/ /*! -* \brief For internal use only. Return the local resolvable private address (RPA). -* -* \param connId Connection ID. -* -* \return Pointer to local RPA. -*/ + * \brief For internal use only. Return the local resolvable private address (RPA). + * + * \param connId Connection ID. + * + * \return Pointer to local RPA. + */ /*************************************************************************************************/ uint8_t *DmConnLocalRpa(dmConnId_t connId); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_handler.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_handler.h index 926afa36c18..5eb11c8078d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_handler.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_handler.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Interface to DM event handler. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Interface to DM event handler. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_HANDLER_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/eatt_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/eatt_api.h new file mode 100644 index 00000000000..15dcee8bf30 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/eatt_api.h @@ -0,0 +1,454 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Enhanced attribute protocol client and server API. + * + * Copyright (c) 2019-2020 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#ifndef EATT_API_H +#define EATT_API_H + +#include "wsf_timer.h" +#include "att_defs.h" +#include "att_uuid.h" +#include "dm_api.h" +#include "l2c_api.h" +#include "cfg_stack.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \addtogroup STACK_ATT_API + * \{ */ +/** \name EATT Role + * EATT role can be initiator or acceptor. + */ +/**@{*/ +#define EATT_ROLE_INITIATOR L2C_COC_ROLE_INITIATOR +#define EATT_ROLE_ACCEPTOR L2C_COC_ROLE_ACCEPTOR +/**@}*/ +/*! \} */ /* STACK_ATT_API */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \addtogroup STACK_ATT_API + * \{ */ +/** + * \name EATT Data Types + * + */ +/**@{*/ +/*! \brief EATT multiple notify tuple structure */ +typedef struct +{ + uint16_t handle; /*!< Attribute handle */ + uint16_t len; /*!< Length of pValue in bytes. */ + uint8_t *pValue; /*!< Attribute value */ +} eattTuple_t; +/**@}*/ +/*! \} */ /* STACK_ATT_API */ + +/*! \addtogroup STACK_ATTS_API + * \{ */ +/** \name EATT Server Functions + * + */ +/**@{*/ +/*************************************************************************************************/ +/*! + * \brief Send multiple attribute protocol Handle Value Notification. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsMultiValueNtf(dmConnId_t connId, uint8_t priority, uint16_t numTuples, eattTuple_t *pTupleList); + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Indication. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueInd(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Notification. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueNtf(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Indication without copying the attribute + * value data. + * + * Note: attribute value buffer 'pValue' must be allocated with AttMsgAlloc(). + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueIndZeroCpy(dmConnId_t connId, uint8_t priority, uint16_t handle, + uint16_t valueLen, uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Notification without copying the attribute + * value data. + * + * Note: attribute value buffer 'pValue' must be allocated with AttMsgAlloc(). + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueNtfZeroCpy(dmConnId_t connId, uint8_t priority, uint16_t handle, + uint16_t valueLen, uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT Server. + * + * \return None + */ + /*************************************************************************************************/ +void EattsInit(); +/**@}*/ +/*! \} */ /* STACK_ATTS_API */ + +/*! \addtogroup STACK_ATTC_API + * \{ */ +/** \name EATT Client Functions + * + */ +/**@{*/ +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Find Information Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcFindInfoReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Find By Type Value Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuid16 16-bit UUID to find. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcFindByTypeValueReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint16_t uuid16, uint16_t valueLen, uint8_t *pValue, bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read By Type Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuidLen Length of UUID (2 or 16). + * \param pUuid Pointer to UUID data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadByTypeReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint8_t uuidLen, uint8_t *pUuid, bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadReq(dmConnId_t connId, uint8_t priority, uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param offset Read attribute data starting at this offset. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadLongReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t offset, bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Multiple Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param numHandles Number of handles in attribute handle list. + * \param pHandles List of attribute handles. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadMultipleReq(dmConnId_t connId, uint8_t priority, uint8_t numHandles, uint16_t *pHandles); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read By Group Type Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuidLen Length of UUID (2 or 16). + * \param pUuid Pointer to UUID data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadByGroupTypeReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint8_t uuidLen, uint8_t *pUuid, bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcWriteReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Cancel an attribute protocol request in progress. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcCancelReq(dmConnId_t connId, uint8_t priority); + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol indication confirmation. + * + * \param connId DM connection ID. + * \param cid L2Cap channel ID. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcIndConfirm(dmConnId_t connId, uint16_t cid); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Write Command. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcWriteCmd(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Prepare Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param offset Write attribute data starting at this offset. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * \param valueByRef TRUE if pValue data is accessed by reference rather than copied. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcPrepareWriteReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t offset, + uint16_t valueLen, uint8_t *pValue, bool_t valueByRef, bool_t continuing); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Execute Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param writeAll TRUE to write all queued writes, FALSE to cancel all queued writes. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcExecuteWriteReq(dmConnId_t connId, uint8_t priority, bool_t writeAll); + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Multiple Variable Length Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param numHandles The number of handles in pHandles. + * \param pHandles List of attribute handles to read. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadMultVarLenReq(dmConnId_t connId, uint8_t priority, uint8_t numHandles, uint16_t *pHandles); + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT Client. + * + * \return None + */ + /*************************************************************************************************/ +void EattcInit(); +/**@}*/ +/*! \} */ /* STACK_ATTC_API */ + +/*! \addtogroup STACK_ATT_API + * \{ */ +/** \name EATT Functions + * + */ +/**@{*/ +/*************************************************************************************************/ +/*! + * \brief Begin requesting EATT L2CAP coc channels. + * + * \note When pEattCfg->initiateEatt is TRUE, EattEstablishChannels is called automatically + * on DM_CONN_OPEN_IND. If pEattCfg->initiateEatt is FALSE, EattEstablishChannels can be + * called by the application after DM_CONN_OPEN_IND to begin creating EATT channels. + * + * \param connId DM connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void EattEstablishChannels(dmConnId_t connId); + +/*************************************************************************************************/ +/*! + * \brief Returns the number of open EATT channels on a given connection. + * + * \param connId DM connection identifier. + * + * \return Number of open EATT channels. + */ +/*************************************************************************************************/ +uint8_t EattGetNumChannelsInUse(dmConnId_t connId); + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT subsystem. + * + * \return None + */ + /*************************************************************************************************/ +void EattInit(uint8_t roleBits); +/**@}*/ +/*! \} */ /* STACK_ATT_API */ + +#ifdef __cplusplus +}; +#endif + +#endif /* EATT_API_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h index 1c90195be4f..5aa513e016f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI subsystem API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI subsystem API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_API_H @@ -31,8 +33,6 @@ extern "C" { #endif - - /************************************************************************************************** Macros **************************************************************************************************/ @@ -47,7 +47,7 @@ extern "C" { #define HCI_RESET_SEQ_CMPL_CBACK_EVT 0 /*!< \brief Reset sequence complete */ #define HCI_LE_CONN_CMPL_CBACK_EVT 1 /*!< \brief LE connection complete */ #define HCI_LE_ENHANCED_CONN_CMPL_CBACK_EVT 2 /*!< \brief LE enhanced connection complete */ -#define HCI_DISCONNECT_CMPL_CBACK_EVT 3 /*!< \brief LE disconnect complete */ +#define HCI_DISCONNECT_CMPL_CBACK_EVT 3 /*!< \brief Disconnect complete */ #define HCI_LE_CONN_UPDATE_CMPL_CBACK_EVT 4 /*!< \brief LE connection update complete */ #define HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL_CBACK_EVT 5 /*!< \brief LE create connection cancel command complete */ #define HCI_LE_ADV_REPORT_CBACK_EVT 6 /*!< \brief LE advertising report */ @@ -112,11 +112,26 @@ extern "C" { #define HCI_LE_CONN_CTE_REQ_ENABLE_CMD_CMPL_CBACK_EVT 65 /*!< \brief LE connection CTE request enable command complete */ #define HCI_LE_CONN_CTE_RSP_ENABLE_CMD_CMPL_CBACK_EVT 66 /*!< \brief LE connection CTE response enable command complete */ #define HCI_LE_READ_ANTENNA_INFO_CMD_CMPL_CBACK_EVT 67 /*!< \brief LE read antenna information command complete */ -#define HCI_CIS_EST_CBACK_EVT 68 /*!< \brief CIS established event */ -#define HCI_CIS_REQ_CBACK_EVT 69 /*!< \brief CIS request event */ -#define HCI_REQ_PEER_SCA_CBACK_EVT 70 /*!< \brief Request peer SCA complete */ +#define HCI_LE_CIS_EST_CBACK_EVT 68 /*!< \brief LE CIS established event */ +#define HCI_LE_CIS_REQ_CBACK_EVT 69 /*!< \brief LE CIS request event */ +#define HCI_CIS_DISCONNECT_CMPL_CBACK_EVT 70 /*!< \brief CIS disconnect complete */ +#define HCI_LE_REQ_PEER_SCA_CBACK_EVT 71 /*!< \brief LE Request peer SCA complete */ +#define HCI_LE_SET_CIG_PARAMS_CMD_CMPL_CBACK_EVT 72 /*!< \brief LE set CIG parameters command complete */ +#define HCI_LE_REMOVE_CIG_CMD_CMPL_CBACK_EVT 73 /*!< \brief LE remove CIG command complete */ +#define HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT 74 /*!< \brief LE setup ISO data path command complete */ +#define HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT 75 /*!< \brief LE remove ISO data path command complete */ +#define HCI_CONFIG_DATA_PATH_CMD_CMPL_CBACK_EVT 76 /*!< \brief Configure data path command complete */ +#define HCI_READ_LOCAL_SUP_CODECS_CMD_CMPL_CBACK_EVT 77 /*!< \brief Read local supported codecs command complete */ +#define HCI_READ_LOCAL_SUP_CODEC_CAP_CMD_CMPL_CBACK_EVT 78 /*!< \brief Read local supported codec capabilities command complete */ +#define HCI_READ_LOCAL_SUP_CTR_DLY_CMD_CMPL_CBACK_EVT 79 /*!< \brief Read local supported controller delay command complete */ +#define HCI_LE_CREATE_BIG_CMPL_CBACK_EVT 80 /*!< \brief LE create BIG complete */ +#define HCI_LE_TERM_BIG_CMPL_CBACK_EVT 81 /*!< \brief LE terminate BIG complete */ +#define HCI_LE_BIG_SYNC_EST_CBACK_EVT 82 /*!< \brief LE BIG sync established */ +#define HCI_LE_BIG_SYNC_LOST_CBACK_EVT 83 /*!< \brief LE BIG sync lost */ +#define HCI_LE_BIG_TERM_SYNC_CMPL_CBACK_EVT 84 /*!< \brief LE BIG terminate sync complete */ +#define HCI_LE_BIG_INFO_ADV_REPORT_CBACK_EVT 85 /*!< \brief LE BIG Info advertising report */ #if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS -#define HCI_UNHANDLED_CMD_CMPL_CBACK_EVT 71 /*!< \brief Unhandled event */ +#define HCI_UNHANDLED_CMD_CMPL_CBACK_EVT 86 /*!< \brief Unhandled event */ #endif /**@}*/ @@ -682,6 +697,217 @@ typedef struct uint8_t cteMaxLen; /*!< \brief Max CTE Length. */ } hciLeReadAntennaInfoCmdCmplEvt_t; +/*! \brief LE CIS established event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint16_t cisHandle; /*!< \brief CIS connection handle. */ + uint32_t cigSyncDelayUsec; /*!< \brief CIG synchronization delay in usec. */ + uint32_t cisSyncDelayUsec; /*!< \brief CIS synchronization delay in usec. */ + uint32_t transLatMToSUsec; /*!< \brief The maximum time, in msec, for transmission of SDUs of all CISes from mater to slave. */ + uint32_t transLatSToMUsec; /*!< \brief The maximum time, in msec, for transmission of SDUs of all CISes from slave to master. */ + uint8_t phyMToS; /*!< \brief Master to slave PHY. */ + uint8_t phySToM; /*!< \brief Slave to master PHY. */ + uint8_t nse; /*!< \brief Number of subevents. */ + uint8_t bnMToS; /*!< \brief Burst number master to slave. */ + uint8_t bnSToM; /*!< \brief Burst number slave to master. */ + uint8_t ftMToS; /*!< \brief Flush timeout master to slave. */ + uint8_t ftSToM; /*!< \brief Flush timeout slave to master. */ + uint16_t maxPduMToS; /*!< \brief Maximum payload size from master to slave. */ + uint16_t maxPduSToM; /*!< \brief Maximum payload size from slave to master. */ + uint16_t isoInterval; /*!< \brief Time between two consecutive ISO anchor points. */ +} HciLeCisEstEvt_t; + +/*! \brief LE CIS request event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint16_t aclHandle; /*!< \brief ACL connection handle. */ + uint16_t cisHandle; /*!< \brief CIS connection handle. */ + uint8_t cigId; /*!< \brief CIG identifier. */ + uint8_t cisId; /*!< \brief CIS identifier. */ +} HciLeCisReqEvt_t; + +/*! \brief LE request peer SCA complete */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint16_t handle; /*!< \brief ACL Connection handle. */ + uint8_t peerSca; /*!< \brief Peer SCA. */ +} HciLeReqPeerScaCmplEvt_t_t; + +/*! \brief LE set CIG parameters command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t cigId; /*!< \brief CIG identifier. */ + uint8_t numCis; /*!< \brief Total number of CISes added or modified. */ + uint16_t cisHandle[HCI_MAX_CIS_COUNT]; /*!< \brief Connection handle of the CISes in the CIG. */ +} hciLeSetCigParamsCmdCmplEvt_t; + +/*! \brief LE remove CIG command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t cigId; /*!< \brief CIG identifier. */ +} hciLeRemoveCigCmdCmplEvt_t; + +/*! \brief LE Create BIG complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t bigHandle; /*!< \brief BIG handle. */ + uint32_t syncDelayUsec; /*!< \brief Synchronization delay in microseconds. */ + uint32_t transLatUsec; /*!< \brief Transport latency, in microseconds. */ + uint8_t phy; /*!< \brief Transmit PHY. */ + uint8_t nse; /*!< \brief Number of Sub-Events in each BIS event in the BIG. */ + uint8_t bn; /*!< \brief Number of new payloads in each BIS event. */ + uint8_t pto; /*!< \brief Offset used for pre-transmissions. */ + uint8_t irc; /*!< \brief Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< \brief Maximum size of the payload. */ + uint16_t isoInterval; /*!< \brief Time between two consecutive ISO anchor points. */ + uint8_t numBis; /*!< \brief Number of BIS. */ + uint16_t bisHandle[HCI_MAX_BIS_COUNT]; /*!< \brief Connection handles of the BIS's. */ +} HciLeCreateBigCmplEvt_t; + +/*! \brief LE Terminate BIG complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t bigHandle; /*!< \brief BIG handle. */ + uint8_t reason; /*!< \brief Terminate reason. */ +} HciLeTerminateBigCmplEvt_t; + +/*! \brief LE BIG Terminate Sync complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t bigHandle; /*!< \brief BIG handle. */ +} HciLeBigTermSyncCmplEvt_t; + +/*! \brief LE BIG Sync Established event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t bigHandle; /*!< \brief BIG handle. */ + uint32_t transLatUsec; /*!< \brief The maximum time, in microseconds, for transmission of SDUs of all BISes. */ + uint8_t nse; /*!< \brief Number of Sub-Events in each BIS event in the BIG. */ + uint8_t bn; /*!< \brief Number of new payloads in each BIS event. */ + uint8_t pto; /*!< \brief Offset used for pre-transmissions. */ + uint8_t irc; /*!< \brief Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< \brief Maximum size of the payload. */ + uint16_t isoInterval; /*!< \brief Time between two consecutive ISO anchor points. */ + uint8_t numBis; /*!< \brief Number of BIS. */ + uint16_t bisHandle[HCI_MAX_BIS_COUNT]; /*!< \brief Connection handles of the BIS's. */ +} HciLeBigSyncEstEvt_t; + +/*! \brief LE BIG sync lost event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t bigHandle; /*!< \brief BIG handle. */ + uint8_t reason; /*!< \brief Sync lost reason. */ +} HciLeBigSyncLostEvt_t; + +/*! \brief LE BIG Info Advertising Report event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint16_t syncHandle; /*!< Sync handle identifying the periodic advertising train. */ + uint8_t numBis; /*!< Number of BIS. */ + uint8_t nse; /*!< Number of Sub-Events in each BIS event in the BIG. */ + uint16_t isoInterv; /*!< ISO interval. */ + uint8_t bn; /*!< Number of new payloads in each BIS event. */ + uint8_t pto; /*!< Offset used for pre-transmissions. */ + uint8_t irc; /*!< Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< Maximum size of the PDU. */ + uint32_t sduInterv; /*!< SDU interval. */ + uint16_t maxSdu; /*!< Maximum size of the SDU. */ + uint8_t phy; /*!< Transmit PHY. */ + uint8_t framing; /*!< Framing mode. */ + bool_t encrypt; /*!< Encryption enabled. */ +} HciLeBigInfoAdvRptEvt_t; + +/*! \brief LE setup ISO data path command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t handle; /*!< \brief Connection handle of the CIS or BIS. */ +} hciLeSetupIsoDataPathCmdCmplEvt_t; + +/*! \brief LE remove ISO data path command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t handle; /*!< \brief Connection handle of the CIS or BIS. */ +} hciLeRemoveIsoDataPathCmdCmplEvt_t; + +/*! \brief Config data path command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ +} hciConfigDataPathCmdCmplEvt_t; + +/*! \brief Standard codec info block */ +typedef struct +{ + uint8_t codecId; /*!< \brief Codec ID. */ +} HciStdCodecInfo_t; + +/*! \brief Vendor-specific codec info block */ +typedef struct +{ + uint16_t compId; /*!< \brief Company ID. */ + uint16_t codecId; /*!< \brief Codec ID. */ +} HciVsCodecInfo_t; + +/*! \brief Read local supported codecs command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t numStdCodecs; /*!< \brief Total number of standard codecs supported. */ + HciStdCodecInfo_t stdCodecs[HCI_MAX_CODEC]; /*!< \brief Standard codecs. */ + uint8_t stdCodecTrans[HCI_MAX_CODEC]; /*!< \brief Standard codec transport. */ + uint8_t numVsCodecs; /*!< \brief Total number of vendor-specific codecs supported. */ + HciVsCodecInfo_t vsCodecs[HCI_MAX_CODEC]; /*!< \brief Vendor-specfic codecs. */ + uint8_t vsCodecTrans[HCI_MAX_CODEC]; /*!< \brief Vendor-specfic codec transport. */ +} hciReadLocalSupCodecsCmdCmplEvt_t; + +/*! \brief Codec capability block */ +typedef struct +{ + uint8_t len; /*!< \brief Length of codec capability. */ + uint8_t data[HCI_CODEC_CAP_DATA_LEN]; /*!< \brief Codec-specific capability data. */ +} HciCodecCap_t; + +/*! \brief Read local supported codec capabilities command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint8_t numCodecCaps; /*!< \bried Number of codec capabilities. */ + HciCodecCap_t codecCap[HCI_MAX_CODEC]; /*!< \brief Codec capabilities. */ +} hciReadLocalSupCodecCapCmdCmplEvt_t; + +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header. */ + uint8_t status; /*!< \brief Status. */ + uint32_t minDly; /*!< \brief Minimum controller delay. */ + uint32_t maxDly; /*!< \brief Maximum controller delay. */ +} hciReadLocalSupCtrDlyCmdCmplEvt_t; + #if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS /*! \brief LE read antenna information command complete event */ typedef struct @@ -694,11 +920,11 @@ typedef struct /*! \brief Local version information */ typedef struct { - uint8_t hciVersion; /*!< \brief HCI version. */ - uint16_t hciRevision; /*!< \brief HCI revision. */ - uint8_t lmpVersion; /*!< \brief LMP version. */ - uint16_t manufacturerName; /*!< \brief Manufacturer name. */ - uint16_t lmpSubversion; /*!< \brief LMP Sub-version. */ + uint8_t hciVersion; /*!< \brief HCI version. */ + uint16_t hciRevision; /*!< \brief HCI revision. */ + uint8_t lmpVersion; /*!< \brief LMP version. */ + uint16_t manufacturerName; /*!< \brief Manufacturer name. */ + uint16_t lmpSubversion; /*!< \brief LMP Sub-version. */ } hciLocalVerInfo_t; /*! \brief Union of all event types */ @@ -766,9 +992,26 @@ typedef union hciLeConnCteReqEnableCmdCmplEvt_t leConnCteReqEnableCmdCmpl; /*!< \brief LE connection CTE request enable command complete. */ hciLeConnCteRspEnableCmdCmplEvt_t leConnCteRspEnableCmdCmpl; /*!< \brief LE connection CTE response enable command complete. */ hciLeReadAntennaInfoCmdCmplEvt_t leReadAntennaInfoCmdCmpl; /*!< \brief LE read antenna information command complete. */ + hciLeSetCigParamsCmdCmplEvt_t leSetCigParamsCmdCmpl; /*!< \brief LE set CIG parameters command complete. */ + hciLeRemoveCigCmdCmplEvt_t leRemoveCigCmdCmpl; /*!< \brief LE remove CIG command complete. */ + HciLeCisEstEvt_t leCisEst; /*!< \brief LE CIS established. */ + HciLeCisReqEvt_t leCisReq; /*!< \brief LE CIS request. */ + HciLeReqPeerScaCmplEvt_t_t leReqPeerSca; /*!< \brief LE request peer SCA complete. */ + hciLeSetupIsoDataPathCmdCmplEvt_t leSetupIsoDataPathCmdCmpl; /*!< \brief LE setup ISO data path command complete. */ + hciLeRemoveIsoDataPathCmdCmplEvt_t leRemoveIsoDataPathCmdCmpl; /*!< \brief LE remove ISO data path command complete. */ + hciConfigDataPathCmdCmplEvt_t configDataPathCmdCmpl; /*!< \brief Config data path command complete. */ + hciReadLocalSupCodecsCmdCmplEvt_t readLocalSupCodecsCmdCmpl; /*!< \brief Read local supported codecs command complete. */ + hciReadLocalSupCodecCapCmdCmplEvt_t readLocalSupCodecCapCmdCmpl; /*!< \brief Read local supported codec capablitlies command complete. */ + hciReadLocalSupCtrDlyCmdCmplEvt_t readLocalSupCtrDlyCmdCmpl; /*!< \brief Read local supported controller delay command complete. */ + HciLeCreateBigCmplEvt_t leCreateBigCmpl; /*!< \brief LE create BIG complete. */ + HciLeTerminateBigCmplEvt_t leTerminateBigCmpl; /*!< \brief LE terminate BIG complete. */ + HciLeBigSyncEstEvt_t leBigSyncEst; /*!< \brief LE BIG sync established. */ + HciLeBigSyncLostEvt_t leBigSyncLost; /*!< \brief LE BIG sync lost. */ + HciLeBigTermSyncCmplEvt_t leBigTermSyncCmpl; /*!< \brief LE BIG terminate sync complete. */ + HciLeBigInfoAdvRptEvt_t leBigInfoAdvRpt; /*!< \brief LE BIG info advertising report. */ #if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS hciUnhandledCmdCmplEvt_t unhandledCmdCmpl; /*!< \brief Unhandled events. */ -#endif +#endif } hciEvt_t; /*! \} */ /* STACK_HCI_EVT_API */ @@ -819,7 +1062,7 @@ typedef struct uint8_t priAdvPhy; /*!< \brief Primary Advertising PHY. */ uint8_t secAdvMaxSkip; /*!< \brief Secondary Advertising Maximum Skip. */ uint8_t secAdvPhy; /*!< \brief Secondary Advertising PHY. */ - uint8_t advSetId; /*!< \brief Advertising set ID. */ + uint8_t advSID; /*!< \brief Advertising SID. */ uint8_t scanReqNotifEna; /*!< \brief Scan Request Notification Enable. */ } hciExtAdvParam_t; @@ -839,6 +1082,115 @@ typedef struct uint8_t scanType; /*!< \brief Scan type. */ } hciExtScanParam_t; +/*! \brief CIS parameters */ +typedef struct +{ + uint8_t cisId; /*!< \brief Used to identify a connected isochronous stream. */ + uint16_t sduSizeMToS; /*!< \brief Maximum size of a data SDU from the master to the slave. */ + uint16_t sduSizeSToM; /*!< \brief Maximum size of a data SDU from the slave to the master. */ + uint8_t phyMToS; /*!< \brief PHY to be used for transmission from master to slave. */ + uint8_t phySToM; /*!< \brief PHY to be used for transmission from master to slave. */ + uint8_t rteMToS; /*!< \brief Maximum number of times every PDU should be retransmitted from the master to slave. */ + uint8_t rteSToM; /*!< \brief Maximum number of times every PDU should be retransmitted from the slave to master. */ +} HciCisCisParams_t; + +/*! \brief CIG parameters */ +typedef struct +{ + uint8_t cigId; /*!< \brief Used to identify the connected isochronous group. */ + uint32_t sduIntervalMToS; /*!< \brief The time interval between the start of consecutive SDUs from the master Host. */ + uint32_t sduIntervalSToM; /*!< \brief The time interval between the start of consecutive SDUs from the slave Host. */ + uint8_t sca; /*!< \brief Sleep clock accuracy. */ + uint8_t packing; /*!< \brief Packing scheme. */ + uint8_t framing; /*!< \brief Indicates the format of CIS Data PDUs. */ + uint16_t transLatMToS; /*!< \brief Maximum time, in milliseconds, for an SDU to be transported from the master Controller to slave Controller. */ + uint16_t transLatSToM; /*!< \brief Maximum time, in milliseconds, for an SDU to be transported from the slave Controller to master Controller. */ + uint8_t numCis; /*!< \brief Number of CIS to set. */ + HciCisCisParams_t *pCisParam; /*!< \brief CIS parameters. */ +} HciCisCigParams_t; + +/*! \brief CIS create CIS parameters */ +typedef struct +{ + uint16_t *pCisHandle; /*!< \brief Pointer to the connected isochronous handle array. */ + uint16_t *pAclHandle; /*!< \brief Pointer to the asynchronous connection link handle array. */ +} HciCisCreateCisParams_t; + +/*! \brief BIG Create BIG parameters */ +typedef struct +{ + uint8_t bigHandle; /*!< \brief Used to identify the BIG. */ + uint8_t advHandle; /*!< \brief Used to identify the periodic advertising train. */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + uint32_t sduInterUsec; /*!< \brief Interval, in microseconds, of BIG SDUs. */ + uint16_t maxSdu; /*!< \brief Maximum size of an SDU. */ + uint16_t mtlMs; /*!< \brief Maximum time in milliseconds. */ + uint8_t rtn; /*!< \brief Retransmitted number. */ + uint8_t phys; /*!< \brief Transmitter PHYs of packets. */ + uint8_t packing; /*!< \brief Sequential or Interleaved packing. */ + uint8_t framing; /*!< \brief Unframed or Framed. */ + uint8_t encrypt; /*!< \brief Unencrypted or Encrypted. */ + uint8_t bcstCode[HCI_BC_LEN]; /*!< \brief Session key used to encrypt and decrypt BIS payloads. */ +} HciCreateBig_t; + +/*! \brief BIG Create Sync parameters */ +typedef struct +{ + uint8_t bigHandle; /*!< \brief Used to identify the BIG. */ + uint16_t syncHandle; /*!< \brief Periodic advertising train handle. */ + uint8_t encrypt; /*!< \brief Unencrypted or Encrypted. */ + uint8_t bcstCode[HCI_BC_LEN]; /*!< \brief Session key code for encrypt and decrypt BIS payloads. */ + uint8_t mse; /*!< \brief Maximum number of subevents. */ + uint16_t bigSyncTimeout; /*!< \brief Synchronization timeout for the BIS, in the units of 10ms. */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + uint8_t bis[HCI_MAX_BIS_COUNT];/*!< \brief List of indices of BISes. */ +} HciBigCreateSync_t; + +/*! \brief Setup ISO data path parameters */ +typedef struct +{ + uint16_t handle; /*!< \brief Handle of CIS or BIS. */ + uint8_t dpDir; /*!< \brief Data path direction. */ + uint8_t dpId; /*!< \brief Data path ID. */ + uint8_t codingFmt; /*!< \brief Coding Format. */ + uint16_t compId; /*!< \brief Company ID (ignored if 'codingFmt' not 0xFF). */ + uint16_t vsCodecId; /*!< \brief Vendor-defined codec ID (ignored if 'codingFmt' not 0xFF). */ + uint32_t ctrDly; /*!< \brief Controller delay (in usec). */ + uint8_t codecConfigLen; /*!< \brief Codec configuration length. */ + uint8_t *pCodecConfig; /*!< \brief Codec configuration. */ +} HciIsoSetupDataPath_t; + +/*! \brief Configure data path parameters */ +typedef struct +{ + uint8_t dpDir; /*!< \brief Data path direction. */ + uint8_t dpId; /*!< \brief Data path ID. */ + uint8_t configLen; /*!< \brief Length of vendor-specific configuration data. */ + uint8_t *pConfig; /*!< \brief Vendor-specific configuration data. */ +} HciConfigDataPath_t; + +/*! \brief Read local supported codec capabilities parameters */ +typedef struct +{ + uint8_t codingFmt; /*!< \brief Coding Format. */ + uint16_t compId; /*!< \brief Company ID (ignored if 'codingFmt' not 0xFF). */ + uint16_t vsCodecId; /*!< \brief Vendor-defined codec ID (ignored if 'codingFmt' not 0xFF). */ + uint8_t transType; /*!< \brief Logical transport type. */ + uint8_t direction; /*!< \brief Direction. */ +} HciReadLocalSupCodecCaps_t; + +/*! \brief Read local supported controller delay parameters */ +typedef struct +{ + uint8_t codingFmt; /*!< \brief Coding Format. */ + uint16_t compId; /*!< \brief Company ID (ignored if 'codingFmt' not 0xFF). */ + uint16_t vsCodecId; /*!< \brief Vendor-defined codec ID (ignored if 'codingFmt' not 0xFF). */ + uint8_t transType; /*!< \brief Logical transport type. */ + uint8_t direction; /*!< \brief Direction. */ + uint8_t codecConfigLen; /*!< \brief Length of codec configuration. */ + uint8_t *pCodecConfig; /*!< \brief Codec-specific configuration data. */ +} HciReadLocalSupControllerDly_t; + /*! \} */ /* STACK_HCI_CMD_API */ /************************************************************************************************** @@ -877,7 +1229,7 @@ typedef void (*hciSecCback_t)(hciEvt_t *pEvent); /*! \brief HCI ACL callback type * - * This callback function sends a data from HCI to the stack. + * This callback function sends ACL data from HCI to the stack. * * \param pData WSF buffer containing an ACL packet. * @@ -885,6 +1237,16 @@ typedef void (*hciSecCback_t)(hciEvt_t *pEvent); */ typedef void (*hciAclCback_t)(uint8_t *pData); +/*! \brief HCI ISO callback type + * + * This callback function sends ISO data from HCI to the stack. + * + * \param pData WSF buffer containing an ISO packet. + * + * \return None. +*/ +typedef void (*hciIsoCback_t)(uint8_t *pData); + /*! \brief HCI flow control callback type * * This callback function manages flow control in the TX path betrween the stack and HCI. @@ -943,6 +1305,18 @@ void HciSecRegister(hciSecCback_t secCback); /*************************************************************************************************/ void HciAclRegister(hciAclCback_t aclCback, hciFlowCback_t flowCback); +/*************************************************************************************************/ +/*! + * \brief Register callbacks for the HCI ISO data path. + * + * \param isoCback ISO data callback function. + * \param flowCback Flow control callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void HciIsoRegister(hciAclCback_t isoCback, hciFlowCback_t flowCback); + /*************************************************************************************************/ /*! * \brief Initiate an HCI reset sequence. @@ -1017,7 +1391,19 @@ void HciSetAclQueueWatermarks(uint8_t queueHi, uint8_t queueLo); * \return None. */ /*************************************************************************************************/ -void HciSetLeSupFeat(uint32_t feat, bool_t flag); +void HciSetLeSupFeat(uint64_t feat, bool_t flag); + +/*************************************************************************************************/ +/*! + * \brief Set LE supported features configuration mask. + * + * \param feat Feature bit to set or clear + * \param flag TRUE to set feature bit and FALSE to clear it + * + * \return None. + */ +/*************************************************************************************************/ +void HciSetLeSupFeat32(uint32_t feat, bool_t flag); /**@}*/ /*************************************************************************************************/ @@ -1104,7 +1490,16 @@ uint8_t *HciGetSupStates(void); * \return Supported features. */ /*************************************************************************************************/ -uint32_t HciGetLeSupFeat(void); +uint64_t HciGetLeSupFeat(void); + +/*************************************************************************************************/ +/*! + * \brief Return the LE supported features supported by the controller. + * + * \return Supported features. + */ +/*************************************************************************************************/ +uint32_t HciGetLeSupFeat32(void); /*************************************************************************************************/ /*! @@ -1345,6 +1740,15 @@ void HciLeReadAdvTXPowerCmd(void); /*************************************************************************************************/ void HciLeReadBufSizeCmd(void); +/*************************************************************************************************/ +/*! + * \brief HCI LE read buffer size version 2 command. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeReadBufSizeCmdV2(void); + /*************************************************************************************************/ /*! * \brief HCI LE read channel map command. @@ -2388,6 +2792,246 @@ void HciLeConnCteRspEnableCmd(uint16_t connHandle, uint8_t enable); */ /*************************************************************************************************/ void HciLeReadAntennaInfoCmd(void); + +/*************************************************************************************************/ +/*! + * \brief HCI LE set CIG parameters command. + * + * \param pCigParam CIG parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeSetCigParamsCmd(HciCisCigParams_t *pCigParam); + +/*************************************************************************************************/ +/*! + * \brief HCI LE create CIS command. + * + * \param numCis Nunber of CISes. + * \param pCreateCisParam Parameters for creating connected isochronous stream. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeCreateCisCmd(uint8_t numCis, HciCisCreateCisParams_t *pCreateCisParam); + +/*************************************************************************************************/ +/*! + * \brief HCI LE accept CIS request command. + * + * \param connHandle Connection handle of the CIS to be accepted. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeAcceptCisReqCmd(uint16_t connHandle); + +/*************************************************************************************************/ +/*! + * \brief HCI LE reject CIS request command. + * + * \param connHandle Connection handle of the CIS to be rejected. + * \param reason Reason the CIS request was rejected. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRejectCisReqCmd(uint16_t connHandle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief HCI LE remove CIG command. + * + * \param cigId Identifer of a CIG. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRemoveCigCmd(uint8_t cigId); + +/*************************************************************************************************/ +/*! + * \brief HCI LE request peer SCA command. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRequestPeerScaCmd(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief HCI LE create BIG command. + * + * \param pCreateBis Create BIG parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeCreateBigCmd(HciCreateBig_t *pCreateBig); + +/*************************************************************************************************/ +/*! + * \brief HCI LE terminate BIG command. + * + * \param bigHandle Used to identify the BIG. + * \param reason Termination reason. + * + * \return None. + */ +/*************************************************************************************************/ +void HciTerminateBigCmd(uint8_t bigHandle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief HCI LE BIG create sync command. + * + * \param pCreateSync BIG Create Sync parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeBigCreateSyncCmd(HciBigCreateSync_t *pCreateSync); + +/*************************************************************************************************/ +/*! + * \brief HCI LE BIG terminate sync command. + * + * \param bigHandle Used to identify the BIG. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeBigTerminateSync(uint8_t bigHandle); + +/*************************************************************************************************/ +/*! + * \brief HCI LE enable ISO Tx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoTxTest(uint16_t handle, uint8_t pldType); + +/*************************************************************************************************/ +/*! + * \brief HCI LE enable ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoRxTest(uint16_t handle, uint8_t pldType); + +/*************************************************************************************************/ +/*! + * \brief HCI LE read ISO test counter. + * + * \param handle CIS or BIS handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoReadTestCounters(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief HCI LE ISO test end. + * + * \param handle CIS or BIS handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoTestEnd(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief HCI LE setup ISO data path command. + * + * \param pDataPathParam Parameters for setup ISO data path. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeSetupIsoDataPathCmd(HciIsoSetupDataPath_t *pDataPathParam); + +/*************************************************************************************************/ +/*! + * \brief HCI LE remove ISO data path command. + * + * \param handle Connection handle of the CIS or BIS. + * \param directionBits Data path direction bits. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRemoveIsoDataPathCmd(uint16_t handle, uint8_t directionBits); + +/*************************************************************************************************/ +/*! + * \brief HCI configure data path command. + * + * \param pDataPathParam Parameters for configuring data path. + * + * \return None. + */ +/*************************************************************************************************/ +void HciConfigDataPathCmd(HciConfigDataPath_t *pDataPathParam); + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported codecs command. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupCodecsCmd(void); + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported codec capabilities command. + * + * \param pCodecParam Parameters to read codec capablilties. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupCodecCapCmd(HciReadLocalSupCodecCaps_t *pCodecParam); + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported controller delay command. + * + * \param pDelayParam Parameters to read controller delay. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupControllerDlyCmd(HciReadLocalSupControllerDly_t *pDelayParam); + +/*************************************************************************************************/ +/*! + * \brief HCI LE set host feature command. + * + * \param bitNum Bit position in the FeatureSet. + * \param bitVal Enable or disable feature. + * + * \return None. + * + * \note Set or clear a bit in the feature controlled by the Host in the Link Layer FeatureSet + * stored in the Controller. + */ +/*************************************************************************************************/ +void HciLeSetHostFeatureCmd(uint8_t bitNum, bool_t bitVal); + /**@}*/ /*! \} */ /* STACK_HCI_CMD_API */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_cmd.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_cmd.h index 65dbbd44234..0341e5bc85a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_cmd.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_cmd.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI command module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_CMD_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_core.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_core.h index 4840f5c3ce3..c165c072055 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_core.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_core.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI core interfaces. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI core interfaces. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_CORE_H @@ -59,10 +61,17 @@ typedef struct uint8_t outBufs; /*!< \brief Outstanding ACL buffers sent to controller */ } hciCoreConn_t; +/*! \brief Per-connection structure for OSI packet accounting */ +typedef struct +{ + uint16_t handle; /*!< \brief Connection handle */ +} hciCoreCis_t; + /*! \brief Main control block for dual-chip implementation */ typedef struct { hciCoreConn_t conn[DM_CONN_MAX]; /*!< \brief Connection structures */ + hciCoreCis_t cis[DM_CIS_MAX]; /*!< \brief CIS structures */ uint8_t leStates[HCI_LE_STATES_LEN]; /*!< \brief Controller LE supported states */ bdAddr_t bdAddr; /*!< \brief Bluetooth device address */ wsfQueue_t aclQueue; /*!< \brief HCI ACL TX queue */ @@ -75,7 +84,7 @@ typedef struct uint8_t numBufs; /*!< \brief Controller number of ACL data buffers */ uint8_t whiteListSize; /*!< \brief Controller white list size */ uint8_t numCmdPkts; /*!< \brief Controller command packed count */ - uint32_t leSupFeat; /*!< \brief Controller LE supported features */ + uint64_t leSupFeat; /*!< \brief Controller LE supported features */ int8_t advTxPwr; /*!< \brief Controller advertising TX power */ uint8_t resListSize; /*!< \brief Controller resolving list size */ uint16_t maxAdvDataLen; /*!< \brief Controller maximum advertisement (or scan response) data length */ @@ -102,7 +111,7 @@ extern const uint8_t hciLeEventMask[HCI_LE_EVT_MASK_LEN]; extern const uint8_t hciEventMaskPage2[HCI_EVT_MASK_LEN]; /*! \brief LE supported features configuration mask */ -extern uint32_t hciLeSupFeatCfg; +extern uint64_t hciLeSupFeatCfg; /************************************************************************************************** Function Declarations @@ -161,6 +170,39 @@ void hciCoreConnClose(uint16_t handle); /*************************************************************************************************/ hciCoreConn_t *hciCoreConnByHandle(uint16_t handle); +/*************************************************************************************************/ +/*! + * \brief Perform internal processing on HCI CIS connection open. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void hciCoreCisOpen(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Perform internal processing on HCI CIS connection close. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void hciCoreCisClose(uint16_t handle); + +/*************************************************************************************************/ +/*! + * \brief Get a CIS connection structure by handle + * + * \param handle Connection handle. + * + * \return Pointer to CIS connection structure or NULL if not found. + */ +/*************************************************************************************************/ +hciCoreCis_t *hciCoreCisByHandle(uint16_t handle); + /*************************************************************************************************/ /*! * \brief Send ACL data to transport. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_drv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_drv.h index a4478ccf3c8..2b3321fcfb4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_drv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_drv.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI driver interface. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2012-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI driver interface. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_DRV_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_evt.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_evt.h index 8432f101934..49577d684c3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_evt.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_evt.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI event module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI event module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_EVT_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_handler.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_handler.h index 7bd5704b7f2..d59d36a05e5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_handler.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_handler.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Interface to HCI event handler. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Interface to HCI event handler. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_HANDLER_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_tr.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_tr.h index a43ad956ae5..243f2e4c70e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_tr.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_tr.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI transport interface. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI transport interface. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_TR_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_api.h index cadf317f4fb..c2a002146de 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_api.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief L2CAP subsystem API. + * \file + * + * \brief L2CAP subsystem API. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef L2C_API_H @@ -81,6 +83,8 @@ enum { L2C_COC_CONNECT_IND = L2C_COC_CBACK_START, /*!< \brief Channel connect indication */ L2C_COC_DISCONNECT_IND, /*!< \brief Channel disconnect indication */ + L2C_COC_EN_CONNECT_IND, /*!< \brief Received enhanced connection indication */ + L2C_COC_EN_RECONFIG_IND, /*!< \brief Received enhanced reconfiguration indication */ L2C_COC_DATA_IND, /*!< \brief Received data indication */ L2C_COC_DATA_CNF /*!< \brief Transmit data confirm */ }; @@ -140,6 +144,28 @@ typedef struct uint16_t cid; /*!< \brief Local channel ID */ } l2cCocDataCnf_t; +/*! \brief Enhanced connection oriented channel connect indication structure */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure */ + uint16_t mps; /*!< \brief Data packet MPS peer can receive */ + uint16_t mtu; /*!< \brief Data packet MTU peer can receive */ + bool_t req; /*!< \brief TRUE if indicating a request, else a response. */ + uint8_t cidLen; /*!< \brief Number of channels in cidList */ + uint16_t cidList[L2C_MAX_EN_CHAN]; /*!< \brief Local channel ID list */ +} l2cCocEnConnectInd_t; + +/*! \brief Enhanced connection oriented channel reconfiguration indication structure */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure */ + uint16_t mps; /*!< \brief Data packet MPS */ + uint16_t mtu; /*!< \brief Data packet MTU */ + bool_t req; /*!< \brief TRUE if indicating a request, else a response. */ + uint8_t cidLen; /*!< \brief Number of channels in cidList */ + uint16_t cidList[L2C_MAX_EN_CHAN]; /*!< \brief Local channel ID list */ +} l2cCocEnReconfigInd_t; + /*! * \brief Connection oriented channel event structure * @@ -156,6 +182,8 @@ typedef union l2cCocDisconnectInd_t disconnectInd; /*!< \brief Channel disconnect indication */ l2cCocDataInd_t dataInd; /*!< \brief Received data indication */ l2cCocDataCnf_t dataCnf; /*!< \brief Transmit data confirm */ + l2cCocEnConnectInd_t enConnectInd; /*!< \brief Enhanced channel connect indication */ + l2cCocEnReconfigInd_t enReconfigInd; /*!< \brief Enhanced channel reconfigure indication */ } l2cCocEvt_t; /*! \brief Configurable parameters */ @@ -227,6 +255,19 @@ typedef void (*l2cCtrlCback_t)(wsfMsgHdr_t *pMsg); /*************************************************************************************************/ typedef void (*l2cCocCback_t)(l2cCocEvt_t *pMsg); +/*************************************************************************************************/ +/*! + * \brief This callback function asks clients of connection oriented channels if a given number + * of channels can be created on the PSM. + * + * \param connId DM connection ID. + * \param numChans number of channels requested. + * + * \return number of channels permitted by client. + */ +/*************************************************************************************************/ +typedef uint8_t (*l2cCocAcceptCb_t)(dmConnId_t connId, uint8_t numChans); + /*************************************************************************************************/ /*! * \brief This callback function is used for authoriztion of connection oriented channels. @@ -369,6 +410,18 @@ l2cCocRegId_t L2cCocRegister(l2cCocCback_t cback, l2cCocReg_t *pReg); /*************************************************************************************************/ void L2cCocDeregister(l2cCocRegId_t regId); +/*************************************************************************************************/ +/*! + * \brief Set the channel accept callback. + * + * \param regId Registration instance ID. + * \param cback Client callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void L2cCocSetAcceptCback(l2cCocRegId_t regId, l2cCocAcceptCb_t cback); + /*************************************************************************************************/ /*! * \brief Initiate a connection to the given peer PSM. @@ -406,6 +459,38 @@ void L2cCocDisconnectReq(uint16_t cid); /*************************************************************************************************/ void L2cCocDataReq(uint16_t cid, uint16_t len, uint8_t *pPayload); +/*************************************************************************************************/ +/*! + * \brief Send a request to open enhanced credit based channels. + * + * \param connId DM connection ID. + * \param regId The associated registration instance. + * \param psm The protocol slave multiplexer. + * \param credits The initial number of credits for each CID channel. + * \param numChan The number of channels to create - L2C_MAX_EN_CHAN max. + * + * \return FALSE if unable make request, else TRUE. + */ +/*************************************************************************************************/ +bool_t L2cCocEnhancedConnectReq(dmConnId_t connId, l2cCocRegId_t regId, uint16_t psm, + uint16_t credits, uint8_t numChan); + +/*************************************************************************************************/ +/*! + * \brief Send a request to reconfigure enhanced credit based channels. + * + * \param connId DM connection ID. + * \param mtu The maximum transmission unit of each source CID channel. + * \param mps The maximum payload size on each source CID channel. + * \param numChan The number of channels to create (1 to L2C_MAX_EN_CHAN). + * \param pChanList A list of local CID to reconfigure (L2C_MAX_EN_CHAN channels, set unused to 0). + * + * \return FALSE if unable make request, else TRUE. + */ + /*************************************************************************************************/ +bool_t L2cCocEnhancedReconfigReq(dmConnId_t connId, uint16_t mtu, uint16_t mps, + uint8_t numChan, uint16_t *pChanList); + /*************************************************************************************************/ /*! * \brief For testing purposes only. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_defs.h index d5e111c4eb1..d32568fd660 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_defs.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_defs.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP constants and definitions from the Bluetooth specification. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP constants and definitions from the Bluetooth specification. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef L2C_DEFS_H @@ -43,6 +45,9 @@ extern "C" { #define L2C_LE_SDU_HDR_LEN 2 /*!< \brief L2CAP LE SDU data header length */ /**@}*/ +/*! \brief Max number of channels per enhanced connection request */ +#define L2C_MAX_EN_CHAN 5 + /*! \brief Start of L2CAP payload in an HCI ACL packet buffer */ #define L2C_PAYLOAD_START (HCI_ACL_HDR_LEN + L2C_HDR_LEN) @@ -64,6 +69,10 @@ extern "C" { #define L2C_SIG_LE_CONN_REQ_LEN 10 /*!< \brief LE connection request length. */ #define L2C_SIG_LE_CONN_RSP_LEN 10 /*!< \brief LE connection response length. */ #define L2C_SIG_FLOW_CTRL_CREDIT_LEN 4 /*!< \brief Flow control credit lenghth. */ +#define L2C_SIG_EN_CONNECT_REQ_LEN 8 /*!< \brief Enhanced credit based connection request */ +#define L2C_SIG_EN_CONNECT_RSP_LEN 8 /*!< \brief Enhanced credit based connection response */ +#define L2C_SIG_EN_RECONFIG_REQ_LEN 4 /*!< \brief Enhanced credit based reconfiguration request */ +#define L2C_SIG_EN_RECONFIG_RSP_LEN 2 /*!< \brief Enhanced credit based reconfiguration response */ /**@}*/ /** \name L2CAP Connection Identifiers @@ -87,6 +96,10 @@ extern "C" { #define L2C_SIG_LE_CONNECT_REQ 0x14 /*!< \brief LE credit based connection request */ #define L2C_SIG_LE_CONNECT_RSP 0x15 /*!< \brief LE credit based connection response */ #define L2C_SIG_FLOW_CTRL_CREDIT 0x16 /*!< \brief LE flow control credit */ +#define L2C_SIG_EN_CONNECT_REQ 0x17 /*!< \brief Enhanced credit based connection request */ +#define L2C_SIG_EN_CONNECT_RSP 0x18 /*!< \brief Enhanced credit based connection response */ +#define L2C_SIG_EN_RECONFIG_REQ 0x19 /*!< \brief Enhanced credit based reconfiguration request */ +#define L2C_SIG_EN_RECONFIG_RSP 0x1A /*!< \brief Enhanced credit based reconfiguration response */ /**@}*/ /*! \brief Signaling response code flag */ @@ -124,6 +137,7 @@ extern "C" { #define L2C_CONN_FAIL_INVALID_SCID 0x0009 /*!< \brief Connection refused invalid source CID */ #define L2C_CONN_FAIL_ALLOCATED_SCID 0x000A /*!< \brief Connection refused source CID already allocated */ #define L2C_CONN_FAIL_UNACCEPT_PARAM 0x000B /*!< \brief Connection refused unacceptable parameters */ +#define L2C_CONN_FAIL_INVALID_PARAM 0x000C /*!< \brief Connection refused invalid parameters */ /**@}*/ /** \name L2CAP Interal Connection Result Codes @@ -147,6 +161,16 @@ extern "C" { #define L2C_CREDITS_MAX 0xFFFF /*!< \brief Credits maximum. */ /**@}*/ +/** \name L2CAP Enhanced Connection Reconfigure Result Codes + * + */ +/**@{*/ +#define L2C_RECONFIG_FAIL_MTU 0x0001 /*!< \brief Enhanced Reconfiguration refuded - cannot reduce MTU. */ +#define L2C_RECONFIG_FAIL_MPS 0x0002 /*!< \brief Enhanced Reconfiguration refuded - cannot reduce MPS on more than one channel. */ +#define L2C_RECONFIG_FAIL_CID 0x0003 /*!< \brief Enhanced Reconfiguration refuded - invalid CID. */ +#define L2C_RECONFIG_FAIL_PARAM 0x0004 /*!< \brief Enhanced Reconfiguration refuded - unacceptable parameters. */ +/**@}*/ + /*! \} */ /*! STACK_L2CAP_API */ #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_handler.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_handler.h index 4507104ab44..1530be120bf 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_handler.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/l2c_handler.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP handler interface. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP handler interface. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef L2C_HANDLER_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/sec_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/sec_api.h index 398b9e57e76..69d231b991e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/sec_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/sec_api.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief AES and random number security service API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief AES and random number security service API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SEC_API_H @@ -38,6 +40,9 @@ extern "C" { /*! \brief CMAC algorithm key length. */ #define SEC_CMAC_KEY_LEN 16 +/*! \brief CMAC algorithm key length. */ +#define SEC_AES_BLK_LEN 16 + /*! \brief CMAC algorithm result length. */ #define SEC_CMAC_HASH_LEN 16 diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_api.h index 4e146e2f161..bf1be72f114 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP subsystem API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP subsystem API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMP_API_H @@ -75,6 +76,7 @@ enum SMP_MSG_WSF_CMAC_CMPL, /*!< \brief WSF CMAC operation complete */ SMP_MSG_DH_CHECK_FAILURE, /*!< \brief DHKey check failure */ SMP_MSG_EARLY_CNF, /*!< \brief An early Confirm from the initiator in passkey pairing */ + SMP_MSG_INT_CLEANUP, /*!< \brief Cleanup control information and return to IDLE state */ SMP_NUM_MSGS /*!< \brief Number of SMP message types. */ }; /**@}*/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_defs.h index 9a21672131c..727952ca205 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_defs.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_defs.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Security manager constants and definitions from the Bluetooth specification. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Security manager constants and definitions from the Bluetooth specification. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMP_DEFS_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_handler.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_handler.h index 381558951fb..2a58681115d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_handler.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/smp_handler.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Interface to SMP event handler. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Interface to SMP event handler. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMP_HANDLER_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h deleted file mode 100644 index 3555b57143c..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h +++ /dev/null @@ -1,171 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Example GATT and GAP service implementations. - */ -/*************************************************************************************************/ - -#ifndef SVC_CORE_H -#define SVC_CORE_H - - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \addtogroup GATT_AND_GAP_SERVICE - * \{ */ - - -/************************************************************************************************** - Handle Ranges -**************************************************************************************************/ -/** \name GAP Service Handles - * \note GAP -- RPAO characterstic added only when DM Privacy enabled - */ -/**@{*/ -#define GAP_START_HDL 0x01 /*!< \brief GAP start handle */ -#define GAP_END_HDL (GAP_MAX_HDL - 3) /*!< \brief GAP end handle */ -/**@}*/ - -/** \name GATT Service Handles - * - */ -/**@{*/ -#define GATT_START_HDL 0x10 /*!< \brief GATT start handle */ -#define GATT_END_HDL (GATT_MAX_HDL - 1) /*!< \brief GATT end handle */ -/**@}*/ - -/************************************************************************************************** - Handles -**************************************************************************************************/ - -/** \name GAP Service Handles - * - */ -/**@{*/ -/*! \brief GAP service handle */ -enum -{ - GAP_SVC_HDL = GAP_START_HDL, /*!< \brief GAP service declaration */ - GAP_DN_CH_HDL, /*!< \brief Device name characteristic */ - GAP_DN_HDL, /*!< \brief Device name */ - GAP_AP_CH_HDL, /*!< \brief Appearance characteristic */ - GAP_AP_HDL, /*!< \brief Appearance */ - GAP_CAR_CH_HDL, /*!< \brief Central address resolution characteristic */ - GAP_CAR_HDL, /*!< \brief Central address resolution */ - GAP_RPAO_CH_HDL, /*!< \brief Resolvable private address only characteristic */ - GAP_RPAO_HDL, /*!< \brief Resolvable private address only */ - GAP_MAX_HDL /*!< \brief GAP maximum handle */ -}; -/**@}*/ - -/** \name GATT Service Handles - * - */ -/**@{*/ -/*! \brief GATT service handles */ -enum -{ - GATT_SVC_HDL = GATT_START_HDL, /*!< \brief GATT service declaration */ - GATT_SC_CH_HDL, /*!< \brief Service changed characteristic */ - GATT_SC_HDL, /*!< \brief Service changed */ - GATT_SC_CH_CCC_HDL, /*!< \brief Service changed client characteristic configuration descriptor */ - GATT_CSF_CH_HDL, /*!< \brief Client supported features characteristic */ - GATT_CSF_HDL, /*!< \brief Client supported features */ - GATT_DBH_CH_HDL, /*!< \brief Database hash characteristic */ - GATT_DBH_HDL, /*!< \brief Database hash */ - GATT_MAX_HDL /*!< \brief GATT maximum handle */ -}; -/**@}*/ - -/************************************************************************************************** - Function Declarations -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Add the services to the attribute server. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreAddGroup(void); - -/*************************************************************************************************/ -/*! - * \brief Remove the services from the attribute server. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreRemoveGroup(void); - -/*************************************************************************************************/ -/*! - * \brief Register callbacks for the service. - * - * \param readCback Read callback function. - * \param writeCback Write callback function. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreGattCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback); - -/*************************************************************************************************/ -/*! - * \brief Register callbacks for the service. - * - * \param readCback Read callback function. - * \param writeCback Write callback function. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreGapCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback); - -/*************************************************************************************************/ -/*! - * \brief Update the central address resolution attribute value. - * - * \param value New value. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreGapCentAddrResUpdate(bool_t value); - -/*************************************************************************************************/ -/*! - * \brief Add the Resolvable Private Address Only (RPAO) characteristic to the GAP service. - * The RPAO characteristic should be added only when DM Privacy is enabled. - * - * \return None. - */ -/*************************************************************************************************/ -void SvcCoreGapAddRpaoCh(void); - -/*! \} */ /* GATT_AND_GAP_SERVICE */ - -#ifdef __cplusplus -}; -#endif - -#endif /* SVC_CORE_H */ - diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/common/hci_core.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/common/hci_core.c index bb7c8ab3113..fe9a1f0cba1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/common/hci_core.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/common/hci_core.c @@ -1,22 +1,27 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief HCI core module, platform independent functions. + * \file + * + * \brief HCI core module, platform independent functions. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This module implements core platform independent HCI features for transmit data path, + * fragmentation, reassembly, and connection management. */ /*************************************************************************************************/ @@ -96,8 +101,16 @@ const uint8_t hciLeEventMask[HCI_LE_EVT_MASK_LEN] = HCI_EVT_MASK_LE_CONN_IQ_REPORT_EVT | /* Byte 2 */ HCI_EVT_MASK_LE_CTE_REQ_FAILED_EVT | /* Byte 2 */ HCI_EVT_MASK_LE_PER_SYNC_TRSF_RCVT_EVT, /* Byte 2 */ - 0, /* Byte 3 */ - 0, /* Byte 4 */ + HCI_EVT_MASK_LE_CIS_EST_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_CIS_REQ_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_CREATE_BIG_CMPL_EVT| /* Byte 3 */ + HCI_EVT_MASK_LE_TERMINATE_BIG_CMPL_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_BIG_SYNC_EST_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_BIG_SYNC_LOST_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_PEER_SCA_CMPL_EVT | /* Byte 3 */ + HCI_EVT_MASK_LE_PATH_LOSS_REPORT_EVT, /* Byte 3 */ + HCI_EVT_MASK_LE_TX_POWER_REPORT_EVT | /* Byte 4 */ + HCI_EVT_MASK_LE_BIG_INFO_ADV_RPT_EVT, /* Byte 4 */ 0, /* Byte 5 */ 0, /* Byte 6 */ 0 /* Byte 7 */ @@ -117,7 +130,7 @@ const uint8_t hciEventMaskPage2[HCI_EVT_MASK_PAGE_2_LEN] = }; /* LE supported features configuration mask */ -uint32_t hciLeSupFeatCfg = +uint64_t hciLeSupFeatCfg = HCI_LE_SUP_FEAT_ENCRYPTION | /* LE Encryption */ HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC | /* Connection Parameters Request Procedure */ HCI_LE_SUP_FEAT_EXT_REJECT_IND | /* Extended Reject Indication */ @@ -126,11 +139,8 @@ uint32_t hciLeSupFeatCfg = HCI_LE_SUP_FEAT_DATA_LEN_EXT | /* LE Data Packet Length Extension */ HCI_LE_SUP_FEAT_PRIVACY | /* LL Privacy */ HCI_LE_SUP_FEAT_EXT_SCAN_FILT_POLICY | /* Extended Scanner Filter Policies */ - HCI_LE_SUP_FEAT_LE_2M_PHY | /* LE 2M PHY supported */ HCI_LE_SUP_FEAT_STABLE_MOD_IDX_TRANSMITTER | /* Stable Modulation Index - Transmitter supported */ - HCI_LE_SUP_FEAT_STABLE_MOD_IDX_RECEIVER | /* Stable Modulation Index - Receiver supported */ - HCI_LE_SUP_FEAT_LE_EXT_ADV | /* LE Extended Advertising */ - HCI_LE_SUP_FEAT_LE_PER_ADV; /* LE Periodic Advertising */ + HCI_LE_SUP_FEAT_STABLE_MOD_IDX_RECEIVER; /* Stable Modulation Index - Receiver supported */ /************************************************************************************************** Global Variables @@ -299,6 +309,119 @@ void hciCoreConnClose(uint16_t handle) hciCoreConnFree(handle); } +/*************************************************************************************************/ +/*! + * \brief Allocate a CIS connection structure. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciCoreCisAlloc(uint16_t handle) +{ + uint8_t i; + hciCoreCis_t *pCis = hciCoreCb.cis; + + /* find available connection struct */ + for (i = DM_CIS_MAX; i > 0; i--, pCis++) + { + if (pCis->handle == HCI_HANDLE_NONE) + { + /* allocate and initialize */ + pCis->handle = handle; + + return; + } + } + + HCI_TRACE_WARN0("HCI cis struct alloc failure"); +} + +/*************************************************************************************************/ +/*! + * \brief Free a CIS connection structure. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciCoreCisFree(uint16_t handle) +{ + uint8_t i; + hciCoreCis_t *pCis = hciCoreCb.cis; + + /* find connection struct */ + for (i = DM_CIS_MAX; i > 0; i--, pCis++) + { + if (pCis->handle == handle) + { + /* free structure */ + pCis->handle = HCI_HANDLE_NONE; + + return; + } + } + + HCI_TRACE_WARN1("hciCoreCisFree handle not found:%u", handle); +} + +/*************************************************************************************************/ +/*! + * \brief Get a CIS connection structure by handle + * + * \param handle Connection handle. + * + * \return Pointer to CIS connection structure or NULL if not found. + */ +/*************************************************************************************************/ +hciCoreCis_t *hciCoreCisByHandle(uint16_t handle) +{ + uint8_t i; + hciCoreCis_t *pCis = hciCoreCb.cis; + + /* find available connection struct */ + for (i = DM_CIS_MAX; i > 0; i--, pCis++) + { + if (pCis->handle == handle) + { + return pCis; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Perform internal processing on HCI CIS connection open. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void hciCoreCisOpen(uint16_t handle) +{ + /* allocate CIS connection structure */ + hciCoreCisAlloc(handle); +} + +/*************************************************************************************************/ +/*! + * \brief Perform internal processing on HCI CIS connection close. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void hciCoreCisClose(uint16_t handle) +{ + /* free CIS connection structure */ + hciCoreCisFree(handle); +} /*************************************************************************************************/ /*! @@ -576,7 +699,7 @@ uint8_t *hciCoreAclReassembly(uint8_t *pData) /* check length vs. configured maximum */ if ((l2cLen + L2C_HDR_LEN) > hciCoreCb.maxRxAclLen) { - HCI_TRACE_WARN1("l2c len=0x%04x to large for reassembly", l2cLen); + HCI_TRACE_WARN2("l2c len=0x%04x to large for reassembly - max: 0x%04x", l2cLen, hciCoreCb.maxRxAclLen - L2C_HDR_LEN); } /* if reassembly required */ else if ((l2cLen + L2C_HDR_LEN) > aclLen) @@ -699,6 +822,11 @@ void HciCoreInit(void) hciCoreCb.conn[i].handle = HCI_HANDLE_NONE; } + for (i = 0; i < DM_CIS_MAX; i++) + { + hciCoreCb.cis[i].handle = HCI_HANDLE_NONE; + } + hciCoreCb.maxRxAclLen = HCI_MAX_RX_ACL_LEN; hciCoreCb.aclQueueHi = HCI_ACL_QUEUE_HI; hciCoreCb.aclQueueLo = HCI_ACL_QUEUE_LO; @@ -763,7 +891,32 @@ void HciSetAclQueueWatermarks(uint8_t queueHi, uint8_t queueLo) * \return None. */ /*************************************************************************************************/ -void HciSetLeSupFeat(uint32_t feat, bool_t flag) +void HciSetLeSupFeat(uint64_t feat, bool_t flag) +{ + /* if asked to include feature */ + if (flag) + { + /* set feature bit */ + hciLeSupFeatCfg |= feat; + } + else + { + /* clear feature bit */ + hciLeSupFeatCfg &= ~feat; + } +} + +/*************************************************************************************************/ +/*! + * \brief Set LE supported features configuration mask. + * + * \param feat Feature bit to set or clear + * \param flag TRUE to set feature bit and FALSE to clear it + * + * \return None. + */ +/*************************************************************************************************/ +void HciSetLeSupFeat32(uint32_t feat, bool_t flag) { /* if asked to include feature */ if (flag) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd.c index d2121feecd7..ac0ead555f1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd.c @@ -1,22 +1,27 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI command module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This module builds and translates HCI command data structures. It also implements command + * flow control. */ /*************************************************************************************************/ @@ -615,6 +620,23 @@ void HciLeReadBufSizeCmd(void) } } +/*************************************************************************************************/ +/*! + * \brief HCI LE read buffer size version 2 command. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeReadBufSizeCmdV2(void) +{ + uint8_t *pBuf; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_READ_BUF_SIZE_V2, HCI_LEN_LE_READ_BUF_SIZE)) != NULL) + { + hciCmdSend(pBuf); + } +} + /*************************************************************************************************/ /*! * \brief HCI LE read channel map command. @@ -1404,6 +1426,55 @@ void HciLeSetPrivacyModeCmd(uint8_t addrType, uint8_t *pAddr, uint8_t mode) } } +/*************************************************************************************************/ +/*! + * \brief HCI LE request peer SCA command. + * + * \param handle Connection handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRequestPeerScaCmd(uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_REQUEST_PEER_SCA, HCI_LEN_LE_REQUEST_PEER_SCA)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE set host feature command. + * + * \param bitNum Bit position in the FeatureSet. + * \param bitVal Enable or disable feature. + * + * \return None. + * + * \note Set or clear a bit in the feature controlled by the Host in the Link Layer FeatureSet + * stored in the Controller. + */ +/*************************************************************************************************/ +void HciLeSetHostFeatureCmd(uint8_t bitNum, bool_t bitVal) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_SET_HOST_FEATURE, HCI_LEN_LE_SET_HOST_FEATURE)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, bitNum); + UINT8_TO_BSTREAM(p, bitVal); + hciCmdSend(pBuf); + } +} + /*************************************************************************************************/ /*! * \brief HCI vencor specific command. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_ae.c index 19d382b12c8..a45398ea488 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief HCI Advertising Extensions (AE) command module. + * \file + * + * \brief HCI Advertising Extensions (AE) command module. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -83,7 +85,7 @@ void HciLeSetExtAdvParamCmd(uint8_t advHandle, hciExtAdvParam_t *pExtAdvParam) UINT8_TO_BSTREAM(p, pExtAdvParam->priAdvPhy); UINT8_TO_BSTREAM(p, pExtAdvParam->secAdvMaxSkip); UINT8_TO_BSTREAM(p, pExtAdvParam->secAdvPhy); - UINT8_TO_BSTREAM(p, pExtAdvParam->advSetId); + UINT8_TO_BSTREAM(p, pExtAdvParam->advSID); UINT8_TO_BSTREAM(p, pExtAdvParam->scanReqNotifEna); hciCmdSend(pBuf); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_bis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_bis.c new file mode 100644 index 00000000000..6f9ec7d0693 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_bis.c @@ -0,0 +1,141 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI Broadcast Isochronous Stream (BIS) command module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "util/bstream.h" +#include "hci_cmd.h" +#include "hci_api.h" +#include "hci_main.h" + +/*************************************************************************************************/ +/*! + * \brief HCI LE create BGS command. + * + * \param pCreateBis Create BIG parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeCreateBigCmd(HciCreateBig_t *pCreateBig) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_CREATE_BIG, HCI_LEN_LE_CREATE_BIS)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pCreateBig->bigHandle); + UINT8_TO_BSTREAM(p, pCreateBig->advHandle); + UINT8_TO_BSTREAM(p, pCreateBig->numBis); + UINT24_TO_BSTREAM(p, pCreateBig->sduInterUsec); + UINT16_TO_BSTREAM(p, pCreateBig->maxSdu); + UINT16_TO_BSTREAM(p, pCreateBig->mtlMs); + UINT8_TO_BSTREAM(p, pCreateBig->rtn); + UINT8_TO_BSTREAM(p, pCreateBig->phys); + UINT8_TO_BSTREAM(p, pCreateBig->packing); + UINT8_TO_BSTREAM(p, pCreateBig->framing); + UINT8_TO_BSTREAM(p, pCreateBig->encrypt); + memcpy(p, pCreateBig->bcstCode, sizeof(pCreateBig->bcstCode)); + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE terminate BIG command. + * + * \param bigHandle Used to identify the BIG. + * \param reason Termination reason. + * + * \return None. + */ + /*************************************************************************************************/ +void HciTerminateBigCmd(uint8_t bigHandle, uint8_t reason) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_TERMINATE_BIG, HCI_LEN_LE_REMOVE_CIG)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, bigHandle); + UINT8_TO_BSTREAM(p, reason); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! +* \brief HCI LE BIG create sync command. +* +* \param pCreateSync BIG Create Sync parameters. +* +* \return Status error code. +*/ +/*************************************************************************************************/ +void HciLeBigCreateSyncCmd(HciBigCreateSync_t *pCreateSync) +{ + uint8_t *pBuf; + uint8_t *p; + uint8_t numBis = WSF_MIN(pCreateSync->numBis, sizeof(pCreateSync->bis)); + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_BIG_CREATE_SYNC, HCI_LEN_LE_BIG_CREATE_SYNC(numBis))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pCreateSync->bigHandle); + UINT16_TO_BSTREAM(p, pCreateSync->syncHandle); + UINT8_TO_BSTREAM(p, pCreateSync->encrypt); + memcpy(p, pCreateSync->bcstCode, sizeof(pCreateSync->bcstCode)); + p += HCI_BC_LEN; + UINT8_TO_BSTREAM(p, pCreateSync->mse); + UINT16_TO_BSTREAM(p, pCreateSync->bigSyncTimeout); + UINT8_TO_BSTREAM(p, pCreateSync->numBis); + memcpy(p, pCreateSync->bis, numBis); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE BIG terminate sync command. + * + * \param bigHandle Used to identify the BIG. + * + * \return None. +*/ +/*************************************************************************************************/ +void HciLeBigTerminateSync(uint8_t bigHandle) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_BIG_TERMINATE_SYNC, HCI_LEN_LE_BIG_TERMINATE_SYNC)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, bigHandle); + hciCmdSend(pBuf); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cis.c new file mode 100644 index 00000000000..e78a247822a --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cis.c @@ -0,0 +1,173 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI Connected Isochronous Stream (CIS) command module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_msg.h" +#include "util/bstream.h" +#include "hci_cmd.h" +#include "hci_api.h" +#include "hci_main.h" + +/*************************************************************************************************/ +/*! + * \brief HCI LE set CIG parameters command. + * + * \param pCigParam CIG parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeSetCigParamsCmd(HciCisCigParams_t *pCigParam) +{ + uint8_t *pBuf; + uint8_t *p; + HciCisCisParams_t *pCisParam; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_SET_CIG_PARAMS, + HCI_LEN_LE_SET_CIG_PARAMS(pCigParam->numCis))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pCigParam->cigId); + UINT24_TO_BSTREAM(p, pCigParam->sduIntervalMToS); + UINT24_TO_BSTREAM(p, pCigParam->sduIntervalSToM); + UINT8_TO_BSTREAM(p, pCigParam->sca); + UINT8_TO_BSTREAM(p, pCigParam->packing); + UINT8_TO_BSTREAM(p, pCigParam->framing); + UINT16_TO_BSTREAM(p, pCigParam->transLatMToS); + UINT16_TO_BSTREAM(p, pCigParam->transLatSToM); + UINT8_TO_BSTREAM(p, pCigParam->numCis); + + pCisParam = pCigParam->pCisParam; + + for (uint8_t i = pCigParam->numCis; i > 0; i--, pCisParam++) + { + UINT8_TO_BSTREAM(p, pCisParam->cisId); + UINT16_TO_BSTREAM(p, pCisParam->sduSizeMToS); + UINT16_TO_BSTREAM(p, pCisParam->sduSizeSToM); + UINT8_TO_BSTREAM(p, pCisParam->phyMToS); + UINT8_TO_BSTREAM(p, pCisParam->phySToM); + UINT8_TO_BSTREAM(p, pCisParam->rteMToS); + UINT8_TO_BSTREAM(p, pCisParam->rteSToM); + } + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE create CIS command. + * + * \param numCis Nunber of CISes. + * \param pCreateCisParam Parameters for creating connected isochronous stream. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeCreateCisCmd(uint8_t numCis, HciCisCreateCisParams_t *pCreateCisParam) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_CREATE_CIS, HCI_LEN_LE_CREATE_CIS(numCis))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, numCis); + + for (; numCis > 0; numCis--, pCreateCisParam++) + { + UINT16_TO_BSTREAM(p, *pCreateCisParam->pCisHandle); + UINT16_TO_BSTREAM(p, *pCreateCisParam->pAclHandle); + } + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE remove CIG command. + * + * \param cigId Identifer of a CIG. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRemoveCigCmd(uint8_t cigId) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_REMOVE_CIG, HCI_LEN_LE_REMOVE_CIG)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, cigId); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE accept CIS request command. + * + * \param handle Connection handle of the CIS to be accepted. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeAcceptCisReqCmd(uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_ACCEPT_CIS_REQ, HCI_LEN_LE_ACCEPT_CIS_REQ)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE reject CIS request command. + * + * \param handle Connection handle of the CIS to be rejected. + * \param reason Reason the CIS request was rejected. + * + * \return None. +*/ +/*************************************************************************************************/ +void HciLeRejectCisReqCmd(uint16_t handle, uint8_t reason) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_REJECT_CIS_REQ, HCI_LEN_LE_REJECT_CIS_REQ)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + UINT8_TO_BSTREAM(p, reason); + hciCmdSend(pBuf); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cte.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cte.c index 711e3f0403c..8011183f9fb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cte.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_cte.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI Constant Tone Extension (CTE) command module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI Constant Tone Extension (CTE) command module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_iso.c new file mode 100644 index 00000000000..557a800e76d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_iso.c @@ -0,0 +1,284 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI Isochronous (ISO) data path command module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_msg.h" +#include "util/bstream.h" +#include "hci_cmd.h" +#include "hci_api.h" +#include "hci_main.h" + +/*************************************************************************************************/ +/*! + * \brief HCI LE enable ISO Tx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoTxTest(uint16_t handle, uint8_t pldType) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_ISO_TX_TEST, HCI_LEN_LE_ISO_TX_TEST)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + UINT8_TO_BSTREAM(p, pldType); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE enable ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoRxTest(uint16_t handle, uint8_t pldType) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_ISO_RX_TEST, HCI_LEN_LE_ISO_RX_TEST)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + UINT8_TO_BSTREAM(p, pldType); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE read ISO test counter. + * + * \param handle CIS or BIS handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoReadTestCounters(uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS, HCI_LEN_LE_ISO_READ_TEST_COUNTERS)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE ISO test end. + * + * \param handle CIS or BIS handle. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeIsoTestEnd(uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_ISO_TEST_END, HCI_LEN_LE_ISO_TEST_END)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE setup ISO data path command. + * + * \param pDataPathParam Parameters for setup ISO data path. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeSetupIsoDataPathCmd(HciIsoSetupDataPath_t *pDataPathParam) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_SETUP_ISO_DATA_PATH, + HCI_LEN_LE_SETUP_ISO_DATA_PATH(pDataPathParam->codecConfigLen))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, pDataPathParam->handle); + UINT8_TO_BSTREAM(p, pDataPathParam->dpDir); + UINT8_TO_BSTREAM(p, pDataPathParam->dpId); + UINT8_TO_BSTREAM(p, pDataPathParam->codingFmt); + UINT16_TO_BSTREAM(p, pDataPathParam->compId); + UINT16_TO_BSTREAM(p, pDataPathParam->vsCodecId); + UINT24_TO_BSTREAM(p, pDataPathParam->ctrDly); + UINT8_TO_BSTREAM(p, pDataPathParam->codecConfigLen); + + memcpy(p, pDataPathParam->pCodecConfig, pDataPathParam->codecConfigLen); + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI LE remove ISO data path command. + * + * \param handle Connection handle of the CIS or BIS. + * \param directionBits Data path direction bits. + * + * \return None. + */ +/*************************************************************************************************/ +void HciLeRemoveIsoDataPathCmd(uint16_t handle, uint8_t directionBits) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH, + HCI_LEN_LE_REMOVE_ISO_DATA_PATH)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT16_TO_BSTREAM(p, handle); + UINT8_TO_BSTREAM(p, directionBits); + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI configure data path command. + * + * \param pDataPathParam Parameters for configuring data path. + * + * \return None. + */ +/*************************************************************************************************/ +void HciConfigDataPathCmd(HciConfigDataPath_t *pDataPathParam) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_CONFIG_DATA_PATH, + HCI_LEN_CONFIG_DATA_PATH(pDataPathParam->configLen))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pDataPathParam->dpDir); + UINT8_TO_BSTREAM(p, pDataPathParam->dpId); + UINT8_TO_BSTREAM(p, pDataPathParam->configLen); + + memcpy(p, pDataPathParam->pConfig, pDataPathParam->configLen); + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported codecs command. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupCodecsCmd(void) +{ + uint8_t *pBuf; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_READ_LOCAL_SUP_CODECS, + HCI_LEN_READ_LOCAL_SUP_CODECS)) != NULL) + { + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported codec capabilities command. + * + * \param pCodecParam Parameters to read codec capablilties. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupCodecCapCmd(HciReadLocalSupCodecCaps_t *pCodecParam) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP, + HCI_LEN_READ_LOCAL_SUP_CODEC_CAP)) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pCodecParam->codingFmt); + UINT16_TO_BSTREAM(p, pCodecParam->compId); + UINT16_TO_BSTREAM(p, pCodecParam->vsCodecId); + UINT8_TO_BSTREAM(p, pCodecParam->transType); + UINT8_TO_BSTREAM(p, pCodecParam->direction); + + hciCmdSend(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI read local supported controller delay command. + * + * \param pDelayParam Parameters to read controller delay. + * + * \return None. + */ +/*************************************************************************************************/ +void HciReadLocalSupControllerDlyCmd(HciReadLocalSupControllerDly_t *pDelayParam) +{ + uint8_t *pBuf; + uint8_t *p; + + if ((pBuf = hciCmdAlloc(HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY, + HCI_LEN_READ_LOCAL_SUP_CONTROLLER_DLY(pDelayParam->codecConfigLen))) != NULL) + { + p = pBuf + HCI_CMD_HDR_LEN; + UINT8_TO_BSTREAM(p, pDelayParam->codingFmt); + UINT16_TO_BSTREAM(p, pDelayParam->compId); + UINT16_TO_BSTREAM(p, pDelayParam->vsCodecId); + UINT8_TO_BSTREAM(p, pDelayParam->transType); + UINT8_TO_BSTREAM(p, pDelayParam->direction); + UINT8_TO_BSTREAM(p, pDelayParam->codecConfigLen); + + memcpy(p, pDelayParam->pCodecConfig, pDelayParam->codecConfigLen); + + hciCmdSend(pBuf); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_past.c index a2da0214d9c..bb8441480a5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_past.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI Periodic Advertising Sync Transfer (PAST) command module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI Periodic Advertising Sync Transfer (PAST) command module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_phy.c index e9ef9a54cb1..e7bb445bb08 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_cmd_phy.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI PHY command module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI PHY command module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.c index 0a868375d6c..0730013ce6d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.c @@ -1,22 +1,28 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI core platform-specific module for dual-chip. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI core platform-specific module for dual-chip. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This module implements core platform-dependent HCI features for transmit data path, receive + * data path, the “optimization” API, and the main event handler. This module contains separate + * implementations for dual chip and single chip. */ /*************************************************************************************************/ @@ -117,6 +123,10 @@ void hciCoreRecv(uint8_t msgType, uint8_t *pCoreRecvMsg) { HCI_PDUMP_RX_ACL(*(pCoreRecvMsg + 2) + HCI_ACL_HDR_LEN, pCoreRecvMsg); } + else if (msgType == HCI_ISO_TYPE) + { + HCI_PDUMP_RX_ISO(*(pCoreRecvMsg + 2) + HCI_ACL_HDR_LEN, pCoreRecvMsg); + } /* queue buffer */ WsfMsgEnq(&hciCb.rxQueue, (wsfHandlerId_t) msgType, pCoreRecvMsg); @@ -171,7 +181,7 @@ void HciCoreHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) WsfMsgFree(pBuf); } /* Handle ACL data */ - else + else if (handlerId == HCI_ACL_TYPE) { /* Reassemble */ if ((pBuf = hciCoreAclReassembly(pBuf)) != NULL) @@ -180,6 +190,20 @@ void HciCoreHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) hciCb.aclCback(pBuf); } } + /* Handle ISO data */ + else + { + if (hciCb.isoCback) + { + /* Call ISO callback; client will free buffer */ + hciCb.isoCback(pBuf); + } + else + { + /* free buffer */ + WsfMsgFree(pBuf); + } + } } } } @@ -263,11 +287,23 @@ uint8_t *HciGetSupStates(void) * \return Supported features. */ /*************************************************************************************************/ -uint32_t HciGetLeSupFeat(void) +uint64_t HciGetLeSupFeat(void) { return hciCoreCb.leSupFeat; } +/*************************************************************************************************/ +/*! + * \brief Return the LE supported features supported by the controller. + * + * \return Supported features. + */ +/*************************************************************************************************/ +uint32_t HciGetLeSupFeat32(void) +{ + return (uint32_t) hciCoreCb.leSupFeat; +} + /*************************************************************************************************/ /*! * \brief Get the maximum reassembled RX ACL packet length. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h index f332dda297d..ebfe18ec5b7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI core platform-specific interfaces for dual-chip. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI core platform-specific interfaces for dual-chip. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_CORE_PS_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c index 265465ad8a3..7537d3d7b80 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c @@ -1,22 +1,27 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI event module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI event module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This module implements parsing and translation of HCI event data structures. This module + * contains separate implementations for dual chip and single chip. */ /*************************************************************************************************/ @@ -24,6 +29,7 @@ #include "wsf_types.h" #include "wsf_buf.h" #include "wsf_trace.h" +#include "wsf_math.h" #include "util/bstream.h" #include "hci_api.h" #include "hci_main.h" @@ -118,6 +124,23 @@ static void hciEvtParseLeSetConnCteTxParamsCmdCmpl(hciEvt_t *pMsg, uint8_t *p, u static void hciEvtParseLeConnCteReqEnableCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); static void hciEvtParseLeConnCteRspEnableCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); static void hciEvtParseLeReadAntennaInfoCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeCisEst(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeCisReq(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeReqPeerScaCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeSetCigParamsCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeRemoveCigCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeSetupIsoDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeRemoveIsoDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseConfigDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseReadLocalSupCodecsCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseReadLocalSupCodecCapCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseReadLocalSupCtrDlyCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeCreateBigCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeTerminateBigCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeBigSyncEst(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeBigSyncLost(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeBigTermSyncCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len); +static void hciEvtParseLeBigInfoAdvRpt(hciEvt_t *pMsg, uint8_t *p, uint8_t len); /************************************************************************************************** Local Variables @@ -193,7 +216,25 @@ static const hciEvtParse_t hciEvtParseFcnTbl[] = hciEvtParseLeSetConnCteTxParamsCmdCmpl, hciEvtParseLeConnCteReqEnableCmdCmpl, hciEvtParseLeConnCteRspEnableCmdCmpl, - hciEvtParseLeReadAntennaInfoCmdCmpl + hciEvtParseLeReadAntennaInfoCmdCmpl, + hciEvtParseLeCisEst, + hciEvtParseLeCisReq, + hciEvtParseDisconnectCmpl, + hciEvtParseLeReqPeerScaCmpl, + hciEvtParseLeSetCigParamsCmdCmpl, + hciEvtParseLeRemoveCigCmdCmpl, + hciEvtParseLeSetupIsoDataPathCmdCmpl, + hciEvtParseLeRemoveIsoDataPathCmdCmpl, + hciEvtParseConfigDataPathCmdCmpl, + hciEvtParseReadLocalSupCodecsCmdCmpl, + hciEvtParseReadLocalSupCodecCapCmdCmpl, + hciEvtParseReadLocalSupCtrDlyCmdCmpl, + hciEvtParseLeCreateBigCmpl, + hciEvtParseLeTerminateBigCmpl, + hciEvtParseLeBigSyncEst, + hciEvtParseLeBigSyncLost, + hciEvtParseLeBigTermSyncCmpl, + hciEvtParseLeBigInfoAdvRpt }; /* HCI event structure length table, indexed by internal callback event value */ @@ -266,7 +307,25 @@ static const uint8_t hciEvtCbackLen[] = sizeof(hciLeSetConnCteTxParamsCmdCmplEvt_t), sizeof(hciLeConnCteReqEnableCmdCmplEvt_t), sizeof(hciLeConnCteRspEnableCmdCmplEvt_t), - sizeof(hciLeReadAntennaInfoCmdCmplEvt_t) + sizeof(hciLeReadAntennaInfoCmdCmplEvt_t), + sizeof(HciLeCisEstEvt_t), + sizeof(HciLeCisReqEvt_t), + sizeof(hciDisconnectCmplEvt_t), + sizeof(HciLeReqPeerScaCmplEvt_t_t), + sizeof(hciLeSetCigParamsCmdCmplEvt_t), + sizeof(hciLeRemoveCigCmdCmplEvt_t), + sizeof(hciLeSetupIsoDataPathCmdCmplEvt_t), + sizeof(hciLeRemoveIsoDataPathCmdCmplEvt_t), + sizeof(hciConfigDataPathCmdCmplEvt_t), + sizeof(hciReadLocalSupCodecsCmdCmplEvt_t), + sizeof(hciReadLocalSupCodecCapCmdCmplEvt_t), + sizeof(hciReadLocalSupCtrDlyCmdCmplEvt_t), + sizeof(HciLeCreateBigCmplEvt_t), + sizeof(HciLeTerminateBigCmplEvt_t), + sizeof(HciLeBigSyncEstEvt_t), + sizeof(HciLeBigSyncLostEvt_t), + sizeof(HciLeBigTermSyncCmplEvt_t), + sizeof(HciLeBigInfoAdvRptEvt_t) }; /* Global event statistics. */ @@ -1802,6 +1861,488 @@ static void hciEvtParseLeReadAntennaInfoCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint pMsg->hdr.status = pMsg->leReadAntennaInfoCmdCmpl.status; } +/*************************************************************************************************/ +/*! + * \brief Process an HCI LE CIS established event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeCisEst(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leCisEst.status, p); + BSTREAM_TO_UINT16(pMsg->leCisEst.cisHandle, p); + BSTREAM_TO_UINT24(pMsg->leCisEst.cigSyncDelayUsec, p); + BSTREAM_TO_UINT24(pMsg->leCisEst.cisSyncDelayUsec, p); + BSTREAM_TO_UINT24(pMsg->leCisEst.transLatMToSUsec, p); + BSTREAM_TO_UINT24(pMsg->leCisEst.transLatSToMUsec, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.phyMToS, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.phySToM, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.nse, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.bnMToS, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.bnSToM, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.ftMToS, p); + BSTREAM_TO_UINT8(pMsg->leCisEst.ftSToM, p); + BSTREAM_TO_UINT16(pMsg->leCisEst.maxPduMToS, p); + BSTREAM_TO_UINT16(pMsg->leCisEst.maxPduSToM, p); + BSTREAM_TO_UINT16(pMsg->leCisEst.isoInterval, p); + + pMsg->hdr.status = pMsg->leCisEst.status; + pMsg->hdr.param = pMsg->leCisEst.cisHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Process an HCI LE CIS request event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeCisReq(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT16(pMsg->leCisReq.aclHandle, p); + BSTREAM_TO_UINT16(pMsg->leCisReq.cisHandle, p); + BSTREAM_TO_UINT8(pMsg->leCisReq.cigId, p); + BSTREAM_TO_UINT8(pMsg->leCisReq.cisId, p); + + pMsg->hdr.param = pMsg->leCisReq.cisHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Process an HCI LE request peer SCA complete event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeReqPeerScaCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leReqPeerSca.status, p); + BSTREAM_TO_UINT16(pMsg->leReqPeerSca.handle, p); + BSTREAM_TO_UINT8(pMsg->leReqPeerSca.peerSca, p); + + pMsg->hdr.status = pMsg->leReqPeerSca.status; + pMsg->hdr.param = pMsg->leReqPeerSca.handle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the LE set CIG parameters command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeSetCigParamsCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + uint16_t *pCisHandle = pMsg->leSetCigParamsCmdCmpl.cisHandle; + + BSTREAM_TO_UINT8(pMsg->leSetCigParamsCmdCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leSetCigParamsCmdCmpl.cigId, p); + BSTREAM_TO_UINT8(pMsg->leSetCigParamsCmdCmpl.numCis, p); + + if (pMsg->leSetCigParamsCmdCmpl.numCis > HCI_MAX_CIS_COUNT) + { + pMsg->leSetCigParamsCmdCmpl.numCis = HCI_MAX_CIS_COUNT; + } + + for (uint8_t i = pMsg->leSetCigParamsCmdCmpl.numCis; i > 0; i--, pCisHandle++) + { + BSTREAM_TO_UINT16(*pCisHandle, p); + } + + pMsg->hdr.status = pMsg->leSetCigParamsCmdCmpl.status; + pMsg->hdr.param = pMsg->leSetCigParamsCmdCmpl.cigId; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the LE remove CIG command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeRemoveCigCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leRemoveCigCmdCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leRemoveCigCmdCmpl.cigId, p); + + pMsg->hdr.status = pMsg->leRemoveCigCmdCmpl.status; + pMsg->hdr.param = pMsg->leRemoveCigCmdCmpl.cigId; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the LE setup ISO data path command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeSetupIsoDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leSetupIsoDataPathCmdCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leSetupIsoDataPathCmdCmpl.handle, p); + + pMsg->hdr.status = pMsg->leSetupIsoDataPathCmdCmpl.status; + pMsg->hdr.param = pMsg->leSetupIsoDataPathCmdCmpl.handle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the LE remove ISO data path command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeRemoveIsoDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leRemoveIsoDataPathCmdCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leRemoveIsoDataPathCmdCmpl.handle, p); + + pMsg->hdr.status = pMsg->leRemoveIsoDataPathCmdCmpl.status; + pMsg->hdr.param = pMsg->leRemoveIsoDataPathCmdCmpl.handle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the configure data path command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseConfigDataPathCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->configDataPathCmdCmpl.status, p); + + pMsg->hdr.status = pMsg->configDataPathCmdCmpl.status; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the read local supported codecs command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseReadLocalSupCodecsCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + uint8_t numCodecs; + + BSTREAM_TO_UINT8(pMsg->readLocalSupCodecsCmdCmpl.status, p); + BSTREAM_TO_UINT8(numCodecs, p); + + pMsg->readLocalSupCodecsCmdCmpl.numStdCodecs = WSF_MIN(numCodecs, HCI_MAX_CODEC); + for (uint8_t i = 0; i < pMsg->readLocalSupCodecsCmdCmpl.numStdCodecs; i++) + { + BSTREAM_TO_UINT8(pMsg->readLocalSupCodecsCmdCmpl.stdCodecs[i].codecId, p); + BSTREAM_TO_UINT8(pMsg->readLocalSupCodecsCmdCmpl.stdCodecTrans[i], p); + } + + if (numCodecs > HCI_MAX_CODEC) + { + /* ignore remaining standard codec info */ + HCI_TRACE_WARN1("Standard codec info block(s) dropped: %d", numCodecs - HCI_MAX_CODEC); + + p += (numCodecs - HCI_MAX_CODEC) * 2; + } + + BSTREAM_TO_UINT8(numCodecs, p); + + pMsg->readLocalSupCodecsCmdCmpl.numVsCodecs = WSF_MIN(numCodecs, HCI_MAX_CODEC); + for (uint8_t i = 0; i < pMsg->readLocalSupCodecsCmdCmpl.numVsCodecs; i++) + { + BSTREAM_TO_UINT16(pMsg->readLocalSupCodecsCmdCmpl.vsCodecs[i].compId, p); + BSTREAM_TO_UINT16(pMsg->readLocalSupCodecsCmdCmpl.vsCodecs[i].codecId, p); + BSTREAM_TO_UINT8(pMsg->readLocalSupCodecsCmdCmpl.vsCodecTrans[i], p); + } + + if (numCodecs > HCI_MAX_CODEC) + { + /* ignore remaining vendor-specific codec info */ + HCI_TRACE_WARN1("Vendor-specific codec info block(s) dropped: %d", numCodecs - HCI_MAX_CODEC); + } + + pMsg->hdr.status = pMsg->readLocalSupCodecsCmdCmpl.status; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the read local supported codec capabilities + * command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseReadLocalSupCodecCapCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + uint8_t numCodecs, dataLen; + + BSTREAM_TO_UINT8(pMsg->readLocalSupCodecCapCmdCmpl.status, p); + BSTREAM_TO_UINT8(numCodecs, p); + + pMsg->readLocalSupCodecCapCmdCmpl.numCodecCaps = WSF_MIN(numCodecs, HCI_MAX_CODEC); + for (uint8_t i = 0; i < pMsg->readLocalSupCodecCapCmdCmpl.numCodecCaps; i++) + { + BSTREAM_TO_UINT8(dataLen, p); + + pMsg->readLocalSupCodecCapCmdCmpl.codecCap[i].len = WSF_MIN(dataLen, HCI_CODEC_CAP_DATA_LEN); + memcpy(pMsg->readLocalSupCodecCapCmdCmpl.codecCap[i].data, p, + pMsg->readLocalSupCodecCapCmdCmpl.codecCap[i].len); + p += dataLen; + + if (dataLen > HCI_CODEC_CAP_DATA_LEN) + { + /* ignore remaining codec-specfic data */ + HCI_TRACE_WARN1("Codec-specific data dropped: %d", dataLen - HCI_CODEC_CAP_DATA_LEN); + } + } + + if (numCodecs > HCI_MAX_CODEC) + { + /* ignore remaining codec capability info */ + HCI_TRACE_WARN1("Codec capability block(s) dropped: %d", numCodecs - HCI_MAX_CODEC); + } + + pMsg->hdr.status = pMsg->readLocalSupCodecCapCmdCmpl.status; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI Command Complete event for the read local supported controller delay + * command. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseReadLocalSupCtrDlyCmdCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->readLocalSupCtrDlyCmdCmpl.status, p); + BSTREAM_TO_UINT24(pMsg->readLocalSupCtrDlyCmdCmpl.minDly, p); + BSTREAM_TO_UINT24(pMsg->readLocalSupCtrDlyCmdCmpl.maxDly, p); + + pMsg->hdr.status = pMsg->readLocalSupCtrDlyCmdCmpl.status; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE create BIG complete event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeCreateBigCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + uint8_t numBis; + + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.bigHandle, p); + BSTREAM_TO_UINT24(pMsg->leCreateBigCmpl.syncDelayUsec, p); + BSTREAM_TO_UINT24(pMsg->leCreateBigCmpl.transLatUsec, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.phy, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.nse, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.bn, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.pto, p); + BSTREAM_TO_UINT8(pMsg->leCreateBigCmpl.irc, p); + BSTREAM_TO_UINT16(pMsg->leCreateBigCmpl.maxPdu, p); + BSTREAM_TO_UINT16(pMsg->leCreateBigCmpl.isoInterval, p); + BSTREAM_TO_UINT8(numBis, p); + + pMsg->leCreateBigCmpl.numBis = WSF_MIN(numBis, HCI_MAX_BIS_COUNT); + for (uint8_t i = 0; i < pMsg->leCreateBigCmpl.numBis; i++) + { + BSTREAM_TO_UINT16(pMsg->leCreateBigCmpl.bisHandle[i], p); + } + + if (numBis > HCI_MAX_BIS_COUNT) + { + /* ignore remaining BIS handles */ + HCI_TRACE_WARN1("BIS handle(s) dropped: %d", numBis - HCI_MAX_BIS_COUNT); + } + + pMsg->hdr.status = pMsg->leCreateBigCmpl.status; + pMsg->hdr.param = pMsg->leCreateBigCmpl.bigHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE terminate BIG complete event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeTerminateBigCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leTerminateBigCmpl.bigHandle, p); + BSTREAM_TO_UINT8(pMsg->leTerminateBigCmpl.reason, p); + + pMsg->hdr.status = pMsg->leTerminateBigCmpl.reason; + pMsg->hdr.param = pMsg->leTerminateBigCmpl.bigHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE BIG sync established event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeBigSyncEst(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + uint8_t numBis; + + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.status, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.bigHandle, p); + BSTREAM_TO_UINT24(pMsg->leBigSyncEst.transLatUsec, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.nse, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.bn, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.pto, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncEst.irc, p); + BSTREAM_TO_UINT16(pMsg->leBigSyncEst.maxPdu, p); + BSTREAM_TO_UINT16(pMsg->leBigSyncEst.isoInterval, p); + BSTREAM_TO_UINT8(numBis, p); + + pMsg->leBigSyncEst.numBis = WSF_MIN(numBis, HCI_MAX_BIS_COUNT); + for (uint8_t i = 0; i < pMsg->leBigSyncEst.numBis; i++) + { + BSTREAM_TO_UINT16(pMsg->leBigSyncEst.bisHandle[i], p); + } + + if (numBis > HCI_MAX_BIS_COUNT) + { + /* ignore remaining BIS handles */ + HCI_TRACE_WARN1("BIS handle(s) dropped: %d", numBis - HCI_MAX_BIS_COUNT); + } + + pMsg->hdr.status = pMsg->leBigSyncEst.status; + pMsg->hdr.param = pMsg->leBigSyncEst.bigHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE BIG sync lost event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeBigSyncLost(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leBigSyncLost.bigHandle, p); + BSTREAM_TO_UINT8(pMsg->leBigSyncLost.reason, p); + + pMsg->hdr.status = pMsg->leBigSyncLost.reason; + pMsg->hdr.param = pMsg->leBigSyncLost.bigHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE BIG terminate sync complete event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeBigTermSyncCmpl(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT8(pMsg->leBigTermSyncCmpl.status, p); + BSTREAM_TO_UINT8(pMsg->leBigTermSyncCmpl.bigHandle, p); + + pMsg->hdr.status = pMsg->leBigTermSyncCmpl.status; + pMsg->hdr.param = pMsg->leBigTermSyncCmpl.bigHandle; +} + +/*************************************************************************************************/ +/*! + * \brief Parse an HCI LE BIG Info advertising report event. + * + * \param pMsg Pointer to output event message structure. + * \param p Pointer to input HCI event parameter byte stream. + * \param len Parameter byte stream length. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciEvtParseLeBigInfoAdvRpt(hciEvt_t *pMsg, uint8_t *p, uint8_t len) +{ + BSTREAM_TO_UINT16(pMsg->leBigInfoAdvRpt.syncHandle, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.numBis, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.nse, p); + BSTREAM_TO_UINT16(pMsg->leBigInfoAdvRpt.isoInterv, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.bn, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.pto, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.irc, p); + BSTREAM_TO_UINT16(pMsg->leBigInfoAdvRpt.maxPdu, p); + BSTREAM_TO_UINT24(pMsg->leBigInfoAdvRpt.sduInterv, p); + BSTREAM_TO_UINT16(pMsg->leBigInfoAdvRpt.maxSdu, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.phy, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.framing, p); + BSTREAM_TO_UINT8(pMsg->leBigInfoAdvRpt.encrypt, p); + + pMsg->hdr.status = HCI_SUCCESS; + pMsg->hdr.param = pMsg->leBigInfoAdvRpt.syncHandle; +} + /*************************************************************************************************/ /*! * \brief Process HCI command status event with failure status. @@ -1833,8 +2374,8 @@ void hciEvtCmdStatusFailure(uint8_t status, uint16_t opcode) break; } #if 0 - handle these events: - translate the command status event into other appropriate event + /* TODO handle these events: + translate the command status event into other appropriate event */ HCI_OPCODE_DISCONNECT HCI_OPCODE_LE_CREATE_CONN HCI_OPCODE_LE_CONN_UPDATE @@ -2042,6 +2583,42 @@ void hciEvtProcessCmdCmpl(uint8_t *p, uint8_t len) cbackEvt = HCI_LE_PER_ADV_SET_INFO_TRSF_CMD_CMPL_CBACK_EVT; break; + case HCI_OPCODE_LE_SET_CIG_PARAMS: + cbackEvt = HCI_LE_SET_CIG_PARAMS_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_LE_REMOVE_CIG: + cbackEvt = HCI_LE_REMOVE_CIG_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_LE_BIG_TERMINATE_SYNC: + cbackEvt = HCI_LE_BIG_TERM_SYNC_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_LE_SETUP_ISO_DATA_PATH: + cbackEvt = HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH: + cbackEvt = HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_CONFIG_DATA_PATH: + cbackEvt = HCI_CONFIG_DATA_PATH_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_READ_LOCAL_SUP_CODECS: + cbackEvt = HCI_READ_LOCAL_SUP_CODECS_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP: + cbackEvt = HCI_READ_LOCAL_SUP_CODEC_CAP_CMD_CMPL_CBACK_EVT; + break; + + case HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY: + cbackEvt = HCI_READ_LOCAL_SUP_CTR_DLY_CMD_CMPL_CBACK_EVT; + break; + default: /* test for vendor specific command completion OGF. */ if (HCI_OGF(opcode) == HCI_OGF_VENDOR_SPEC) @@ -2274,6 +2851,44 @@ void hciEvtProcessMsg(uint8_t *pEvt) cbackEvt = HCI_LE_CTE_REQ_FAILED_CBACK_EVT; break; + case HCI_LE_CIS_EST_EVT: + /* if CIS connection created successfully */ + if (*pEvt == HCI_SUCCESS) + { + BYTES_TO_UINT16(handle, (pEvt + 1)); + hciCoreCisOpen(handle); + } + cbackEvt = HCI_LE_CIS_EST_CBACK_EVT; + break; + + case HCI_LE_CIS_REQ_EVT: + cbackEvt = HCI_LE_CIS_REQ_CBACK_EVT; + break; + + case HCI_LE_CREATE_BIG_CMPL_EVT: + cbackEvt = HCI_LE_CREATE_BIG_CMPL_CBACK_EVT; + break; + + case HCI_LE_TERMINATE_BIG_CMPL_EVT: + cbackEvt = HCI_LE_TERM_BIG_CMPL_CBACK_EVT; + break; + + case HCI_LE_BIG_SYNC_EST_EVT: + cbackEvt = HCI_LE_BIG_SYNC_EST_CBACK_EVT; + break; + + case HCI_LE_BIG_SYNC_LOST_EVT: + cbackEvt = HCI_LE_BIG_SYNC_LOST_CBACK_EVT; + break; + + case HCI_LE_REQ_PEER_SCA_CMPLT_EVT: + cbackEvt = HCI_LE_REQ_PEER_SCA_CBACK_EVT; + break; + + case HCI_LE_BIG_INFO_ADV_REPORT_EVT: + cbackEvt = HCI_LE_BIG_INFO_ADV_REPORT_CBACK_EVT; + break; + default: break; } @@ -2281,7 +2896,17 @@ void hciEvtProcessMsg(uint8_t *pEvt) case HCI_DISCONNECT_CMPL_EVT: hciEvtStats.numDiscCmplEvt++; - cbackEvt = HCI_DISCONNECT_CMPL_CBACK_EVT; + + /* if disconnect is for CIS connection */ + BYTES_TO_UINT16(handle, (pEvt + 1)); + if (hciCoreCisByHandle(handle) != NULL) + { + cbackEvt = HCI_CIS_DISCONNECT_CMPL_CBACK_EVT; + } + else + { + cbackEvt = HCI_DISCONNECT_CMPL_CBACK_EVT; + } break; case HCI_ENC_CHANGE_EVT: @@ -2366,6 +2991,11 @@ void hciEvtProcessMsg(uint8_t *pEvt) BYTES_TO_UINT16(handle, (pEvt + 1)); hciCoreConnClose(handle); } + else if (cbackEvt == HCI_CIS_DISCONNECT_CMPL_CBACK_EVT) + { + BYTES_TO_UINT16(handle, (pEvt + 1)); + hciCoreCisClose(handle); + } } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_vs_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_vs_ae.c index d926d5a15ab..45bca96a104 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_vs_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_vs_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI vendor specific AE functions for generic controllers. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI vendor specific AE functions for generic controllers. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes.c index 63351efda56..a7863c142e7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief AES and random number security service implemented using HCI. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief AES and random number security service implemented using HCI. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes_rev.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes_rev.c new file mode 100644 index 00000000000..5f0bf2c4d62 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_aes_rev.c @@ -0,0 +1,137 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief AES and random number security service implemented using HCI. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_queue.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "sec_api.h" +#include "sec_main.h" +#include "hci_api.h" +#include "util/calc128.h" +#include "util/wstr.h" + +/************************************************************************************************** + External Variables +**************************************************************************************************/ + +extern secCb_t secCb; + +/*************************************************************************************************/ +/*! + * \brief Returns the next token. + * + * \return Token value. + */ +/*************************************************************************************************/ +static uint8_t getNextToken() +{ + uint8_t token = secCb.token++; + + if (token == SEC_TOKEN_INVALID) + { + token = secCb.token++; + } + + return token; +} + +/*************************************************************************************************/ +/*! + * \brief Execute an AES calculation. When the calculation completes, a WSF message will be + * sent to the specified handler. This function returns a token value that + * the client can use to match calls to this function with messages. Note this version + * reverses the key and plaintext bytes. + * + * \param pKey Pointer to 16 byte key. + * \param pPlaintext Pointer to 16 byte plaintext. + * \param handlerId WSF handler ID. + * \param param Client-defined parameter returned in message. + * \param event Event for client's WSF handler. + * + * \return Token value. + */ +/*************************************************************************************************/ +uint8_t SecAesRev(uint8_t *pKey, uint8_t *pPlaintext, wsfHandlerId_t handlerId, + uint16_t param, uint8_t event) +{ + secQueueBuf_t *pBuf; + + /* allocate a buffer */ + if ((pBuf = WsfMsgAlloc(sizeof(secQueueBuf_t))) != NULL) + { + pBuf->msg.hdr.status = getNextToken(); + pBuf->msg.hdr.param = param; + pBuf->msg.hdr.event = event; + + pBuf->type = SEC_TYPE_AES_REV; + + /* call HCI encrypt function */ + SecLeEncryptCmd(pKey, pPlaintext, pBuf, handlerId); + + return pBuf->msg.hdr.status; + } + + return SEC_TOKEN_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Callback for HCI encryption for AES operations. Note this version reverses the + * ciphertext bytes. + * + * \param pBuf Pointer to sec queue element. + * \param pEvent Pointer to HCI event. + * \param handlerId WSF handler ID. + * + * \return none. + */ +/*************************************************************************************************/ +void SecAesRevHciCback(secQueueBuf_t *pBuf, hciEvt_t *pEvent, wsfHandlerId_t handlerId) +{ + secAes_t *pAes = (secAes_t *) &pBuf->msg; + + /* set encrypted data pointer and copy */ + pAes->pCiphertext = pBuf->ciphertext; + + Calc128Cpy(pAes->pCiphertext, pEvent->leEncryptCmdCmpl.data); + + /* send message */ + WsfMsgSend(handlerId, pAes); +} + +/*************************************************************************************************/ +/*! + * \brief Called to initialize AES secuirity. + * + * \param none. + * + * \return none. + */ +/*************************************************************************************************/ +void SecAesRevInit() +{ + secCb.hciCbackTbl[SEC_TYPE_AES_REV] = SecAesRevHciCback; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ccm_hci.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ccm_hci.c index 6740808d6d6..afa8bf8610d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ccm_hci.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ccm_hci.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Counter with CBC-MAC (CCM) mode security - HCI AES. + * \file + * + * \brief Counter with CBC-MAC (CCM) mode security - HCI AES. + * + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_cmac_hci.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_cmac_hci.c index 591678f308d..f177a886936 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_cmac_hci.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_cmac_hci.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief AES and random number security service implemented using HCI. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief AES and random number security service implemented using HCI. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c new file mode 100644 index 00000000000..1ab2e8583d1 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c @@ -0,0 +1,160 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Security ECC implementation using debug keys. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include +#include +#include "wsf_types.h" +#include "wsf_queue.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "sec_api.h" +#include "sec_main.h" +#include "wsf_buf.h" +#include "hci_api.h" +#include "util/calc128.h" + +#ifndef SEC_ECC_CFG +#define SEC_ECC_CFG SEC_ECC_CFG_DEBUG +#endif + +#if SEC_ECC_CFG == SEC_ECC_CFG_DEBUG + +/* Debug Keys */ +static const uint8_t debugPrivateKey[] = {0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, + 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50, + 0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, + 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd}; + +static const uint8_t debugPublicKeyX[] = {0x20, 0xb0, 0x03, 0xd2, 0xf2, 0x97, 0xbe, 0x2c, + 0x5e, 0x2c, 0x83, 0xa7, 0xe9, 0xf9, 0xa5, 0xb9, + 0xef, 0xf4, 0x91, 0x11, 0xac, 0xf4, 0xfd, 0xdb, + 0xcc, 0x03, 0x01, 0x48, 0x0e, 0x35, 0x9d, 0xe6}; + +static const uint8_t debugPublicKeyY[] = {0xdc, 0x80, 0x9c, 0x49, 0x65, 0x2a, 0xeb, 0x6d, + 0x63, 0x32, 0x9a, 0xbf, 0x5a, 0x52, 0x15, 0x5c, + 0x76, 0x63, 0x45, 0xc2, 0x8f, 0xed, 0x30, 0x24, + 0x74, 0x1c, 0x8e, 0xd0, 0x15, 0x89, 0xd2, 0x8b}; + +static const uint8_t debugSharedSecret[] = {0x49, 0x4c, 0xfd, 0x99, 0x6f, 0x40, 0x17, 0xf5, + 0xb5, 0x48, 0xba, 0x66, 0x99, 0x60, 0x64, 0x08, + 0x62, 0x75, 0xd5, 0x1f, 0xe0, 0x8e, 0x56, 0x36, + 0xb9, 0x36, 0xd1, 0xe4, 0x57, 0x46, 0x4b, 0xed}; + +/*************************************************************************************************/ +/*! + * \brief Callback for HCI encryption for ECC operations. + * + * \param pBuf Pointer to sec queue element. + * \param pEvent Pointer to HCI event. + * \param handlerId WSF handler ID. + * + * \return none. + */ +/*************************************************************************************************/ +void SecEccHciCback(secQueueBuf_t *pBuf, hciEvt_t *pEvent, wsfHandlerId_t handlerId) +{ +} + +/*************************************************************************************************/ +/*! + * \brief Generate an ECC key. + * + * \param handlerId WSF handler ID for client. + * \param param Optional parameter sent to client's WSF handler. + * \param event Event for client's WSF handler. + * + * \return TRUE if successful, else FALSE. + */ +/*************************************************************************************************/ +bool_t SecEccGenKey(wsfHandlerId_t handlerId, uint16_t param, uint8_t event) +{ + secEccMsg_t *pMsg = WsfMsgAlloc(sizeof(secEccMsg_t)); + + if (pMsg) + { + /* Generate the keys */ + memcpy(pMsg->data.key.pubKey_x, debugPublicKeyX, SEC_ECC_KEY_LEN); + memcpy(pMsg->data.key.pubKey_y, debugPublicKeyY, SEC_ECC_KEY_LEN); + memcpy(pMsg->data.key.privKey, debugPrivateKey, SEC_ECC_KEY_LEN); + + /* Send shared secret to handler */ + pMsg->hdr.event = event; + pMsg->hdr.param = param; + pMsg->hdr.status = HCI_SUCCESS; + WsfMsgSend(handlerId, pMsg); + + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Generate an ECC key. + * + * \param pKey ECC Key structure. + * \param handlerId WSF handler ID for client. + * \param param Optional parameter sent to client's WSF handler. + * \param event Event for client's WSF handler. + * + * \return TRUE if successful, else FALSE. + */ +/*************************************************************************************************/ +bool_t SecEccGenSharedSecret(secEccKey_t *pKey, wsfHandlerId_t handlerId, uint16_t param, uint8_t event) +{ + secEccMsg_t *pMsg = WsfMsgAlloc(sizeof(secEccMsg_t)); + + if (pMsg) + { + memcpy(pMsg->data.sharedSecret.secret, debugSharedSecret, SEC_ECC_KEY_LEN); + + /* Send shared secret to handler */ + pMsg->hdr.event = event; + pMsg->hdr.param = param; + pMsg->hdr.status = HCI_SUCCESS; + WsfMsgSend(handlerId, pMsg); + + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Called to initialize ECC security. + * + * \param None. + * + * \return None. + */ +/*************************************************************************************************/ +void SecEccInit() +{ + +} + +#endif /* SEC_ECC_CFG */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_hci.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_hci.c index f85dcc33e5f..11ddd9a0cb3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_hci.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_hci.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief WSF Security ECC implementation using HCI. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief WSF Security ECC implementation using HCI. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.c index e847b9f7030..452f0e8623f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Security service implemented using HCI. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Security service implemented using HCI. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -31,7 +33,7 @@ #include "hci_api.h" #include "util/calc128.h" #include "util/wstr.h" -#include "stack/platform/include/pal_crypto.h" +#include "pal_crypto.h" /************************************************************************************************** Global Variables @@ -64,14 +66,17 @@ static void secHciCback(hciEvt_t *pEvent) case HCI_LE_ENCRYPT_CMD_CMPL_CBACK_EVT: pBuf = WsfMsgDeq(&secCb.aesEncQueue, &handlerId); - - WSF_ASSERT(pBuf != NULL); - - /* note: pBuf should never be NULL and is checked by assert above. */ - /* coverity[dereference] */ - if (pBuf->type == SEC_TYPE_CCM || pBuf->type == SEC_TYPE_CMAC || pBuf->type == SEC_TYPE_AES_REV) + if (pBuf != NULL) + { + if (pBuf->type == SEC_TYPE_CCM || pBuf->type == SEC_TYPE_CMAC || pBuf->type == SEC_TYPE_AES_REV) + { + WStrReverse(pEvent->leEncryptCmdCmpl.data, HCI_ENCRYPT_DATA_LEN); + } + } + else { - WStrReverse(pEvent->leEncryptCmdCmpl.data, HCI_ENCRYPT_DATA_LEN); + /* Should never happen */ + WSF_ASSERT(0); } break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.h index ac2b7f6cb26..17e670fa2bc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_main.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal security service structures. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Internal security service structures. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SEC_MAIN_H #define SEC_MAIN_H #include "hci_api.h" -#include "stack/platform/include/pal_crypto.h" +#include "pal_crypto.h" #ifdef __cplusplus extern "C" { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/pal/sec_ccm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/pal/sec_ccm.c deleted file mode 100644 index 5be321772a3..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/pal/sec_ccm.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Counter with CBC-MAC (CCM) mode security - Native AES. - */ -/*************************************************************************************************/ - -#include -#include "wsf_types.h" -#include "wsf_buf.h" -#include "wsf_msg.h" -#include "sec_api.h" -#include "sec_main.h" - -#ifndef SEC_CCM_CFG -#define SEC_CCM_CFG SEC_CCM_CFG_PLATFORM -#endif - -#if SEC_CCM_CFG == SEC_CCM_CFG_PLATFORM - -/************************************************************************************************** - External Variables -**************************************************************************************************/ - -/* Global security control block */ -extern secCb_t secCb; - -/*************************************************************************************************/ -/*! - * \brief Execute the CCM-Mode encryption algorithm. - * - * \param pKey Pointer to encryption key (SEC_CCM_KEY_LEN bytes). - * \param pNonce Pointer to nonce (SEC_CCM_NONCE_LEN bytes). - * \param pPlainText Pointer to text to encrypt. - * \param textLen Length of pPlainText in bytes. - * \param pClear Pointer to additional, unencrypted authentication text. - * \param clearLen Length of pClear in bytes. - * \param micLen Size of MIC in bytes (4, 8 or 16). - * \param pResult Buffer to hold result (returned in complete event). - * \param handlerId Task handler ID to receive complete event. - * \param param Optional parameter passed in complete event. - * \param event Event ID of complete event. - - * \return TRUE if successful, else FALSE. - */ -/*************************************************************************************************/ -bool_t SecCcmEnc(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pPlainText, uint16_t textLen, - uint8_t *pClear, uint16_t clearLen, uint8_t micLen, uint8_t *pResult, - wsfHandlerId_t handlerId, uint16_t param, uint8_t event) -{ - secCcmEncMsg_t *pCcmMsg; - - if ((pCcmMsg = WsfMsgAlloc(sizeof(secCcmEncMsg_t))) != NULL) - { - /* Encrypt. */ - PalCryptoCcmEnc(pKey, pNonce, pPlainText, textLen, pClear, clearLen, micLen, pResult, - handlerId, param, event); - - memcpy(pResult, pClear, clearLen); - - /* Send notification of encryption complete. */ - pCcmMsg->hdr.status = secCb.token++; - pCcmMsg->hdr.param = param; - pCcmMsg->hdr.event = event; - pCcmMsg->pCiphertext = pResult; - pCcmMsg->textLen = textLen + clearLen + micLen; - WsfMsgSend(handlerId, pCcmMsg); - - return TRUE; - } - - return FALSE; -} - -/*************************************************************************************************/ -/*! - * \fn SecCcmDec - * - * \brief Execute the CCM-Mode verify and decrypt algorithm. - * - * \param pKey Pointer to encryption key (SEC_CCM_KEY_LEN bytes). - * \param pNonce Pointer to nonce (SEC_CCM_NONCE_LEN bytes). - * \param pCypherText Pointer to text to decrypt. - * \param textLen Length of pCypherText in bytes. - * \param pClear Pointer to additional, unencrypted authentication text. - * \param clearLen Length of pClear in bytes. - * \param pMic Pointer to authentication digest. - * \param micLen Size of MIC in bytes (4, 8 or 16). - * \param pResult Buffer to hold result (returned in complete event). - * \param handlerId Task handler ID to receive complete event. - * \param param Optional parameter passed in complete event. - * \param event Event ID of complete event. - * - * \return TRUE if successful, else FALSE. - */ -/*************************************************************************************************/ -bool_t SecCcmDec(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pCypherText, uint16_t textLen, - uint8_t *pClear, uint16_t clearLen, uint8_t *pMic, uint8_t micLen, - uint8_t *pResult, wsfHandlerId_t handlerId, uint16_t param, uint8_t event) -{ - secCcmDecMsg_t *pCcmMsg; - - if ((pCcmMsg = WsfMsgAlloc(sizeof(secCcmDecMsg_t))) != NULL) - { - /* Decrypt. */ - uint32_t error; - - error = PalCryptoCcmDec(pKey, pNonce, pCypherText, textLen, pClear, clearLen, pMic, micLen, - pResult, handlerId, param, event); - - /* Send notification of decryption complete. */ - pCcmMsg->hdr.status = secCb.token++; - pCcmMsg->hdr.param = param; - pCcmMsg->hdr.event = event; - - /* Compare MIC with computed MIC. */ - if (error) - { - /* MIC not authentic. */ - pCcmMsg->success = FALSE; - pCcmMsg->pResult = NULL; - pCcmMsg->pText = NULL; - pCcmMsg->textLen = 0; - } - else - { - /* MIC authentic. */ - pCcmMsg->success = TRUE; - pCcmMsg->pResult = pResult; - pCcmMsg->pText = pResult; - pCcmMsg->textLen = textLen; - } - - WsfMsgSend(handlerId, pCcmMsg); - - return TRUE; - } - - return FALSE; - -} - -/*************************************************************************************************/ -/*! - * \brief Called to initialize CCM-Mode security. - * - * \return None. - */ -/*************************************************************************************************/ -void SecCcmInit() -{ - PalCryptoInit(); - - secCb.hciCbackTbl[SEC_TYPE_CCM] = NULL; -} - -#endif /* SEC_CCM_CFG */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.c new file mode 100644 index 00000000000..330d9efe93e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.c @@ -0,0 +1,938 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Enhanced ATT (EATT) main module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_timer.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_os.h" +#include "util/bstream.h" +#include "att_api.h" +#include "eatt_api.h" +#include "att_main.h" +#include "att_eatt.h" +#include "l2c_api.h" +#include "l2c_main.h" +#include "dm_api.h" +#include "cfg_stack.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/* EATT PSM identifier */ +#define EATT_PSM 0x0027 + +/* Initial number of credits on EATT L2CAP COC channels */ +#define EATT_INIT_CREDITS 1 + +/* EATT Connect state machine states */ +enum { + EATT_CONN_STATE_IDLE = 0, /* Idle state */ + EATT_CONN_STATE_INITIATING, /* Initiating connections state */ + EATT_CONN_STATE_RECONFIG, /* Reconfiguring MTU/MPS state */ + EATT_CONN_STATE_ACCEPTING /* Accepting connections state */ +}; + +/* EATT Connect state machine events */ +#define EATT_BACKOFF_EVT EATT_MSG_START + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +eattCb_t eattCb; + +/* Channel control block list. */ +#if EATT_CONN_CHAN_MAX > 0 +eattChanCb_t eattChanCb[DM_CONN_MAX][EATT_CONN_CHAN_MAX]; +#endif + +/************************************************************************************************** + External Variables +**************************************************************************************************/ + +/* EATT application configuration */ +extern eattCfg_t *pEattCfg; + +/* ATT control block */ +extern attCb_t attCb; + +/*************************************************************************************************/ +/*! + * \brief Calculate a random backoff period for establishing enhanced channels. + * + * \return Backoff period. + */ +/*************************************************************************************************/ +static wsfTimerTicks_t eattBackoffPeriod(uint16_t connInterval) +{ + uint16_t randMs; + uint16_t minInterval = (uint16_t) (2 * 1.25 * connInterval); + + /* Get a random value */ + SecRand((uint8_t*) &randMs, sizeof(randMs)); + + /* Limit random value to 1024ms */ + randMs &= 0x3FF; + + /* Ensure the random time is greater than 2x the connection interval */ + randMs = (randMs > minInterval) ? randMs : randMs + minInterval; + + return randMs; +} + +/*************************************************************************************************/ +/*! + * \brief Get an EATT connection control block. + * + * \param connId DM connection identifier. + * + * \return Pointer to control block. + */ +/*************************************************************************************************/ +eattConnCb_t *eattGetConnCb(dmConnId_t connId) +{ + WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX)); + + return &eattCb.ccb[connId - 1]; +} + +/*************************************************************************************************/ +/*! + * \brief Get an EATT bearer control block given a bearer slot identifier. + * + * \param connId DM connection identifier. + * \param slot Bearer slot identifier. + * + * \return Pointer to control block. + */ +/*************************************************************************************************/ +eattChanCb_t *eattGetChanCbBySlot(dmConnId_t connId, uint8_t slot) +{ + WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX)); + WSF_ASSERT((slot > 0) && (slot <= EATT_CONN_CHAN_MAX)); + + return &eattCb.ccb[connId - 1].pChanCb[slot - 1]; +} + +/*************************************************************************************************/ +/*! + * \brief Get an EATT bearer control block given an L2CAP channel identifier. + * + * \param connId DM connection identifier. + * \param cid L2CAP channel identifier. + * + * \return Pointer to control block. + */ +/*************************************************************************************************/ +static eattChanCb_t *eattGetChanCbByCid(dmConnId_t connId, uint16_t cid) +{ + eattConnCb_t *pConnCb = eattGetConnCb(connId); + uint8_t i; + + if (pConnCb) + { + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + if (pConnCb->pChanCb[i].cid == cid) + { + return &pConnCb->pChanCb[i]; + } + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Returns an EATT slot identifier given a connection ID and L2CAP channel identifier. + * + * \param connId DM connection identifier. + * \param cid L2CAP channel identifier. + * + * \return slot identifier. + */ +/*************************************************************************************************/ +uint8_t eattGetSlotId(dmConnId_t connId, uint16_t cid) +{ + eattConnCb_t *pCcb = eattGetConnCb(connId); + uint8_t i; + + if (cid == L2C_CID_ATT) + { + return ATT_BEARER_SLOT_ID; + } + + if (pCcb) + { + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + if (pCcb->pChanCb[i].cid == cid) + { + return i + 1; + } + } + } + + return ATT_BEARER_SLOT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Finds an unused slot on a given connection. + * + * \param connId DM connection identifier. + * + * \return EATT slot identifier or ATT_BEARER_SLOT_INVALID. + */ +/*************************************************************************************************/ +static uint8_t eattGetUnusedSlot(dmConnId_t connId) +{ + eattConnCb_t *pCcb = eattGetConnCb(connId); + uint8_t i; + + if (pCcb) + { + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + if (pCcb->pChanCb[i].inUse == FALSE) + { + return i + 1; + } + } + } + + return ATT_BEARER_SLOT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Update the MTU in the ATT control block. + * + * \param connId DM connection identifier. + * \param slot EATT slot identifier. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattUpdateMtu(dmConnId_t connId, uint8_t slot) +{ + eattChanCb_t *pChanCb = eattGetChanCbBySlot(connId, slot); + + if (pChanCb) + { + /* The peer MTU must be greater than or equal to ATT_DEFAULT_MTU. */ + uint16_t peerMtu = WSF_MAX(ATT_DEFAULT_MTU, pChanCb->peerMtu); + + /* Set the ATT mtu to the minimum to the local and peer MTU */ + attCb.ccb[connId-1].sccb[slot].mtu = WSF_MIN(pChanCb->localMtu, peerMtu); + } +} + +/*************************************************************************************************/ +/*! + * \brief L2CAP channel accept callback. + * + * \param connId DM connection identifier. + * \param numChans Number of channels requested by the L2CAP. + * + * \return number of channels permitted by EATT. + */ +/*************************************************************************************************/ +static uint8_t eattL2cCocAcceptCback(dmConnId_t connId, uint8_t numChans) +{ + eattConnCb_t *pCcb = eattGetConnCb(connId); + + if ((pCcb->state == EATT_CONN_STATE_INITIATING) || (pCcb->state == EATT_CONN_STATE_RECONFIG)) + { + // Reject all requests while busy connecting and configuring channels + return 0; + } + + // Limit the number of channels to value define by application in pEattCfg->numChans + uint8_t maxChans = pEattCfg->numChans - EattGetNumChannelsInUse(connId); + return (maxChans > numChans) ? maxChans : numChans; +} + +/*************************************************************************************************/ +/*! + * \brief Reconfigure the next set of L2CAP COC channels. + * + * \param connId DM connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattReconfigureNextChannels(dmConnId_t connId) +{ + eattConnCb_t *pConnCb = eattGetConnCb(connId); + + if (pConnCb) + { + uint16_t chanList[L2C_MAX_EN_CHAN]; + uint8_t numChan = 0; + uint8_t i = 0; + + while ((i < EATT_CONN_CHAN_MAX) && (numChan < L2C_MAX_EN_CHAN)) + { + eattChanCb_t *pChanCb = eattGetChanCbBySlot(connId, i + 1); + + if (pChanCb->inUse) + { + if ((pChanCb->localMtu <= pConnCb->pendingMtu) && (pChanCb->localMps <= pConnCb->pendingMps)) + { + chanList[numChan++] = pChanCb->cid; + } + } + + i++; + } + + if (numChan > 0) + { + bool_t success = L2cCocEnhancedReconfigReq(connId, pConnCb->pendingMtu, pConnCb->pendingMps, + numChan, chanList); + + if (!success) + { + /* Reconfigure failed, notify callback */ + pConnCb->state = EATT_CONN_STATE_IDLE; + eattExecCallback(connId, ATT_EATT_RECONFIG_CMPL_IND, ATT_ERR_RESOURCES); + } + } + else + { + /* Reconfigure complete. */ + pConnCb->state = EATT_CONN_STATE_IDLE; + eattExecCallback(connId, ATT_EATT_RECONFIG_CMPL_IND, ATT_SUCCESS); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Request the next set of channels from the L2CAP. + * + * \param connId DM connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattReqNextChannels(dmConnId_t connId) +{ + bool_t success; + eattConnCb_t *pConnCb = eattGetConnCb(connId); + uint8_t numChans = pEattCfg->numChans - EattGetNumChannelsInUse(connId); + + numChans = (numChans > L2C_MAX_EN_CHAN) ? L2C_MAX_EN_CHAN : numChans; + + EATT_TRACE_INFO1("eattReqNextChannels: numChans: %d", numChans); + + if (numChans > 0) + { + /* Request L2CAP enhanced channels */ + success = L2cCocEnhancedConnectReq(connId, eattCb.cocRegId, EATT_PSM, EATT_INIT_CREDITS, numChans); + + if (!success) + { + /* Connect failed, notify callback */ + pConnCb->state = EATT_CONN_STATE_IDLE; + eattExecCallback(connId, ATT_EATT_CONN_CMPL_IND, ATT_ERR_RESOURCES); + } + } + else + { + /* No more channels to create. */ + pConnCb->state = EATT_CONN_STATE_IDLE; + eattExecCallback(connId, ATT_EATT_CONN_CMPL_IND, ATT_SUCCESS); + } +} + +/*************************************************************************************************/ +/*! + * \brief Process an L2CAP enhanced channel connect indication. + * + * \param pMsg L2Cap connect message. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cEnChanInd(l2cCocEnConnectInd_t *pMsg) +{ + dmConnId_t connId = (dmConnId_t) pMsg->hdr.param; + eattConnCb_t *pCcb = eattGetConnCb(connId); + uint8_t i; + + if (pCcb) + { + if (pMsg->req && (pCcb->state == EATT_CONN_STATE_INITIATING)) + { + /* Shouldn't happen */ + WSF_ASSERT(0); + } + + /* Check status */ + if ((pMsg->hdr.status == L2C_CONN_SUCCESS) || (pMsg->hdr.status == L2C_CONN_FAIL_RES) || + (pMsg->hdr.status == L2C_CONN_FAIL_INVALID_SCID) || (pMsg->hdr.status == L2C_CONN_FAIL_ALLOCATED_SCID)) + { + /* Store connection identifiers */ + for (i = 0; i < L2C_MAX_EN_CHAN; i++) + { + if (pMsg->cidList[i]) + { + uint8_t slot = eattGetUnusedSlot(connId); + + if (slot != ATT_BEARER_SLOT_INVALID) + { + eattChanCb_t *pChanCb = eattGetChanCbBySlot(connId, slot); + + if (pChanCb) + { + pChanCb->cid = pMsg->cidList[i]; + pChanCb->peerMtu = pMsg->mtu; + pChanCb->localMtu = pEattCfg->mtu; + pChanCb->priority = pEattCfg->pPriorityTbl[slot - 1]; + pChanCb->inUse = TRUE; + + eattUpdateMtu(connId, slot); + } + else + { + /* Shouldn't happen */ + WSF_ASSERT(0); + } + } + } + } + + /* When initiating, check if more channels need to be created */ + if (pCcb->state == EATT_CONN_STATE_INITIATING) + { + if (pMsg->hdr.status != L2C_CONN_FAIL_RES) + { + eattReqNextChannels((dmConnId_t)pMsg->hdr.param); + } + else + { + /* Peer will not accept any more channels */ + pCcb->state = EATT_CONN_STATE_IDLE; + } + } + else + { + if (EattGetNumChannelsInUse(connId) == pEattCfg->numChans) + { + /* Max channels reached. */ + pCcb->state = EATT_CONN_STATE_IDLE; + WsfTimerStop(&pCcb->backoffTimer); + } + } + } + else + { + /* Peer cannot accept more channels. */ + pCcb->state = EATT_CONN_STATE_IDLE; + eattExecCallback(connId, ATT_EATT_CONN_CMPL_IND, ATT_SUCCESS); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Process an L2CAP enhanced channel reconfigure indication. + * + * \param pMsg L2Cap reconfigure message. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cEnReconfigInd(l2cCocEnConnectInd_t *pMsg) +{ + dmConnId_t connId = (dmConnId_t) pMsg->hdr.param; + eattConnCb_t *pConnCb = eattGetConnCb(connId); + uint8_t i; + + if (pConnCb) + { + for (i = 0; i < L2C_MAX_EN_CHAN; i++) + { + if (pMsg->cidList[i]) + { + eattChanCb_t *pChanCb = eattGetChanCbByCid(connId, pMsg->cidList[i]); + + if (pChanCb) + { + if (pMsg->req) + { + /* The peer changed their MTU */ + pChanCb->peerMtu = pMsg->mtu; + } + else + { + pChanCb->localMtu = pConnCb->pendingMtu; + pChanCb->localMps = pConnCb->pendingMps; + } + + eattUpdateMtu(connId, i + 1); + } + } + } + + if (!pMsg->req) + { + /* If this was a response, send the next reconfiguration */ + eattReconfigureNextChannels(connId); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Process an L2CAP data indication. + * + * \param pMsg L2Cap indication message. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cDataInd(l2cCocDataInd_t *pMsg) +{ + /* parse PDU type */ + uint8_t pduType = *pMsg->pData; + + /* if from server */ + if ((pduType & ATT_PDU_MASK_SERVER) != 0) + { + /* call client data callback */ + (*attCb.pEnClient->l2cCocData)((l2cCocEvt_t*) pMsg); + } + /* else from client */ + else + { + /* call server data callback */ + (*attCb.pEnServer->l2cCocData)((l2cCocEvt_t*) pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Process an L2CAP data confirmation. + * + * \param pMsg L2Cap confirmation message. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cDataCnf(l2cCocDataCnf_t *pMsg) +{ + attCcb_t *pCcb = attCcbByConnId((dmConnId_t) pMsg->hdr.param); + + if (pCcb) + { + uint8_t slot = eattGetSlotId((dmConnId_t) pMsg->hdr.param, pMsg->cid); + + if (slot != ATT_BEARER_SLOT_INVALID) + { + /* verify connection is open */ + if (pCcb && pCcb->connId != DM_CONN_ID_NONE) + { + if (pMsg->hdr.event == L2C_CTRL_FLOW_DISABLE_IND) + { + /* flow disabled */ + pCcb->sccb[slot].control |= ATT_CCB_STATUS_FLOW_DISABLED; + } + else + { + /* flow enabled */ + pCcb->sccb[slot].control &= ~ATT_CCB_STATUS_FLOW_DISABLED; + + /* call server control callback */ + (*attCb.pEnClient->l2cCocCnf)((l2cCocEvt_t*) pMsg); + + /* check flow again; could be changed recursively */ + if (!(pCcb->sccb[slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) + { + /* call client control callback */ + (*attCb.pEnClient->l2cCocCnf)((l2cCocEvt_t*) pMsg); + } + } + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Process an L2CAP disconnect indication. + * + * \param pMsg L2Cap confirmation message. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cDisconnectInd(l2cCocDisconnectInd_t *pMsg) +{ + eattChanCb_t *pCcb = eattGetChanCbByCid((dmConnId_t) pMsg->hdr.param, pMsg->cid); + + if (pCcb) + { + pCcb->inUse = FALSE; + } +} + +/*************************************************************************************************/ +/*! + * \brief The L2CAP CoC callback function. + * + * \param pMsg Pointer to message structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cCocCback(l2cCocEvt_t *pMsg) +{ + switch (pMsg->hdr.event) + { + case L2C_COC_EN_CONNECT_IND: + eattL2cEnChanInd(&pMsg->enConnectInd); + break; + + case L2C_COC_DISCONNECT_IND: + eattL2cDisconnectInd(&pMsg->disconnectInd); + break; + + case L2C_COC_EN_RECONFIG_IND: + eattL2cEnReconfigInd(&pMsg->enConnectInd); + break; + + case L2C_COC_DATA_IND: + eattL2cDataInd(&pMsg->dataInd); + break; + + case L2C_COC_DATA_CNF: + eattL2cDataCnf(&pMsg->dataCnf); + break; + + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief DM connection callback for EATT. + * + * \param pDmEvt DM callback event. + * + * \return None. + */ +/*************************************************************************************************/ +void eattOnConnOpen(dmEvt_t *pDmEvt) +{ + eattConnCb_t *pCcb = eattGetConnCb((dmConnId_t) pDmEvt->hdr.param); + + if (pCcb) + { + /* Initialize channel control block. */ + memset(&pCcb->backoffTimer, 0, sizeof(wsfTimer_t)); + pCcb->state = EATT_CONN_STATE_IDLE; + pCcb->connInterval = pDmEvt->connOpen.connInterval; + pCcb->pendingMtu = 0; + pCcb->pendingMps = 0; + } +} + +/*************************************************************************************************/ +/*! + * \brief Begin requesting EATT L2CAP coc channels. + * + * \param connId DM connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void EattEstablishChannels(dmConnId_t connId) +{ + if (DmConnInUse(connId)) + { + eattConnCb_t *pCcb = eattGetConnCb(connId); + + EATT_TRACE_INFO1("EattEstablishChannels: connId: %#x", connId); + + if (pCcb) + { + /* Request first set of channels. */ + if (DmConnRole(connId) == DM_ROLE_MASTER) + { + pCcb->state = EATT_CONN_STATE_INITIATING; + eattReqNextChannels(connId); + } + else + { + /* Set a timer to initiate creation of channels */ + pCcb->state = EATT_CONN_STATE_ACCEPTING; + + pCcb->backoffTimer.msg.event = EATT_BACKOFF_EVT; + pCcb->backoffTimer.msg.param = connId; + pCcb->backoffTimer.handlerId = attCb.handlerId; + WsfTimerStartMs(&pCcb->backoffTimer, eattBackoffPeriod(pCcb->connInterval)); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Returns the number of open EATT channels on a given connection. + * + * \param connId DM connection identifier. + * + * \return Number of open EATT channels. + */ +/*************************************************************************************************/ +uint8_t EattGetNumChannelsInUse(dmConnId_t connId) +{ + eattConnCb_t *pCcb = eattGetConnCb(connId); + uint8_t count = 0; + uint8_t i; + + if (pCcb) + { + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + if (pCcb->pChanCb[i].inUse == TRUE) + { + count++; + } + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief DM connection callback for EATT. + * + * \param pDmEvt DM callback event. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattDmCback(dmEvt_t *pDmEvt) +{ + dmConnId_t connId = (dmConnId_t) pDmEvt->hdr.param; + eattConnCb_t *pCcb = eattGetConnCb(connId); + + switch (pDmEvt->hdr.event) + { + case DM_CONN_OPEN_IND: + eattOnConnOpen(pDmEvt); + + if (pEattCfg->initiateEatt) + { + EattEstablishChannels(connId); + } + break; + + case DM_CONN_CLOSE_IND: + WsfTimerStop(&pCcb->backoffTimer); + break; + + case DM_CONN_UPDATE_IND: + if (pCcb) + { + pCcb->connInterval = pDmEvt->connUpdate.connInterval; + } + break; + + default: + break; + } + +} + +/*************************************************************************************************/ +/*! + * \brief Get L2CAP CID given DM channel ID and EATT slot. + * + * \param connId DM channel ID. + * \param slot EATT slot. + * + * \return None + */ +/*************************************************************************************************/ +uint16_t eattGetCid(dmConnId_t connId, uint8_t slot) +{ + if (slot == ATT_BEARER_SLOT_ID) + { + return L2C_CID_ATT; + } + else + { + eattConnCb_t *pCcb = eattGetConnCb(connId); + return pCcb->pChanCb[slot-1].cid; + } +} + +/*************************************************************************************************/ +/*! + * \brief Execute application callback function. + * + * \param connId DM connection ID. + * \param event Callback event ID. + * \param status Status of event. + * + * \return None. + */ +/*************************************************************************************************/ +void eattExecCallback(dmConnId_t connId, uint8_t event, uint8_t status) +{ + if (attCb.cback) + { + attEvt_t evt; + + memset(&evt, 0, sizeof(evt)); + evt.hdr.param = connId; + evt.hdr.event = event; + evt.hdr.status = status; + + (*attCb.cback)(&evt); + } +} + +/*************************************************************************************************/ +/*! + * \brief WSF event handler for EATT. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void eattHandler(wsfMsgHdr_t *pMsg) +{ + if (pMsg->event == EATT_BACKOFF_EVT) + { + dmConnId_t connId = (dmConnId_t) pMsg->param; + eattConnCb_t *pCcb = eattGetConnCb(connId); + + if (pCcb) + { + pCcb->state = EATT_CONN_STATE_INITIATING; + eattReqNextChannels(connId); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Reconfigure the connection's EATT mtu and mps. + * + * \param connId DM channel ID. + * \param mtu New MTU. + * \param mps New MPS. + * + * \return None + */ +/*************************************************************************************************/ +void EattReconfigureChannels(dmConnId_t connId, uint16_t mtu, uint16_t mps) +{ + eattConnCb_t *pConnCb = eattGetConnCb(connId); + + if (pConnCb && (pConnCb->state == EATT_CONN_STATE_IDLE)) + { + pConnCb->pendingMtu = mtu; + pConnCb->pendingMps = mps; + + eattReconfigureNextChannels(connId); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send an L2CAP data packet on the given eatt slott. + * + * \param pCcb ATT control block. + * \param slot EATT channel slot. + * \param handle The connection handle. The client receives this handle from DM. + * \param len The length of the payload data in pPacket. + * \param pPacket A buffer containing the packet. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattL2cDataReq(attCcb_t *pCcb, uint8_t slot, uint16_t len, uint8_t *pPacket) +{ + /* send EATT packet to L2CAP via COC channel for the slot */ + uint16_t cid = eattGetCid(pCcb->connId, slot); + + L2cCocDataReq(cid, len, pPacket + L2C_PAYLOAD_START); + WsfMsgFree(pPacket); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT subsystem. + * + * \return None + */ +/*************************************************************************************************/ +void EattInit(uint8_t roleBits) +{ + l2cCocReg_t reg; + + /* EATT_CONN_CHAN_MAX must be greater than 0 */ + WSF_ASSERT(EATT_CONN_CHAN_MAX); + + /* Register with L2CAP */ + reg.psm = EATT_PSM; + reg.mtu = pEattCfg->mtu; + reg.mps = pEattCfg->mps; + reg.credits = EATT_INIT_CREDITS; + reg.authoriz = pEattCfg->authoriz; + reg.secLevel = pEattCfg->secLevel; + reg.role = roleBits; + + eattCb.cocRegId = L2cCocRegister(eattL2cCocCback, ®); + L2cCocSetAcceptCback(eattCb.cocRegId, eattL2cCocAcceptCback); + + /* Register with DM */ + attCb.eattDmCback = eattDmCback; + + /* Register functions with ATT control block */ + attCb.eattHandler = eattHandler; + attCb.eattL2cDataReq = eattL2cDataReq; + + /* Set the channel control blocks in the connection control blocks */ +#if EATT_CONN_CHAN_MAX > 0 + for (uint8_t i = 0; i < DM_CONN_MAX; i++) + { + eattCb.ccb[i].pChanCb = eattChanCb[i]; + } +#endif +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.h new file mode 100644 index 00000000000..8927fa57461 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_eatt.h @@ -0,0 +1,84 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Enhanced ATT (EATT) main module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#ifndef EATT_MAIN_H +#define EATT_MAIN_H + +#include "wsf_queue.h" +#include "wsf_timer.h" +#include "l2c_api.h" +#include "dm_api.h" +#include "att_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/* EATT channel control block. */ +typedef struct +{ + uint16_t cid; /* L2CAP channel identifier. */ + uint16_t priority; /* Slot priority */ + uint16_t peerMtu; /* Peer MTU of L2CAP channel */ + uint16_t localMtu; /* Local MTU of L2CAP channel */ + uint16_t localMps; /* Local MPS of L2CAP channel */ + bool_t inUse; /* L2CAP channel is open */ +} eattChanCb_t; + +/* EATT connection control block. */ +typedef struct +{ + uint8_t state; /* Connection state. */ + uint16_t pendingMtu; /* Pending MTU */ + uint16_t pendingMps; /* Pending MPS */ + uint16_t connInterval; /* The connection interval. */ + wsfTimer_t backoffTimer; /* Backoff timer for L2CAP en conn req collisions. */ + eattChanCb_t *pChanCb; /* Channel control block list. */ +} eattConnCb_t; + +/* EATT main control block. */ +typedef struct +{ + eattConnCb_t ccb[DM_CONN_MAX]; /* Connection control blocks. */ + l2cCocRegId_t cocRegId; /* L2CAP COC registration ID. */ +} eattCb_t; + +extern eattCb_t eattCb; + +/************************************************************************************************** + Function Prototypes +**************************************************************************************************/ + +uint16_t eattGetCid(dmConnId_t connId, uint8_t slot); +uint8_t eattGetSlotId(dmConnId_t connId, uint16_t cid); +eattConnCb_t *eattGetConnCb(dmConnId_t connId); +void eattHandler(wsfMsgHdr_t *pMsg); +void eattExecCallback(dmConnId_t connId, uint8_t event, uint8_t status); + +#ifdef __cplusplus +}; +#endif + +#endif /* EATT_MAIN_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.c index a921cca5a68..e21a3076668 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief ATT main module. + * \file + * + * \brief ATT main module. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,6 +31,7 @@ #include "wsf_math.h" #include "util/bstream.h" #include "att_api.h" +#include "eatt_api.h" #include "att_main.h" #include "dm_api.h" @@ -60,6 +63,15 @@ const attFcnIf_t attFcnDefault = attEmptyConnCback }; +/* Default component function inteface */ +const eattFcnIf_t eattFcnDefault = +{ + attEmptyL2cCocCback, + attEmptyL2cCocCback, + (attMsgHandler_t) attEmptyHandler, + attEmptyConnCback +}; + /* Control block */ attCb_t attCb; @@ -117,18 +129,18 @@ static void attL2cCtrlCback(wsfMsgHdr_t *pMsg) if (pMsg->event == L2C_CTRL_FLOW_DISABLE_IND) { /* flow disabled */ - pCcb->control |= ATT_CCB_STATUS_FLOW_DISABLED; + pCcb->sccb[ATT_BEARER_SLOT_ID].control |= ATT_CCB_STATUS_FLOW_DISABLED; } else { /* flow enabled */ - pCcb->control &= ~ATT_CCB_STATUS_FLOW_DISABLED; + pCcb->sccb[ATT_BEARER_SLOT_ID].control &= ~ATT_CCB_STATUS_FLOW_DISABLED; /* call server control callback */ (*attCb.pServer->ctrlCback)(pMsg); /* check flow again; could be changed recursively */ - if (!(pCcb->control & ATT_CCB_STATUS_FLOW_DISABLED)) + if (!(pCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_FLOW_DISABLED)) { /* call client control callback */ (*attCb.pClient->ctrlCback)(pMsg); @@ -149,6 +161,7 @@ static void attL2cCtrlCback(wsfMsgHdr_t *pMsg) static void attDmConnCback(dmEvt_t *pDmEvt) { attCcb_t *pCcb; + uint8_t i; pCcb = attCcbByConnId((dmConnId_t) pDmEvt->hdr.param); @@ -157,9 +170,14 @@ static void attDmConnCback(dmEvt_t *pDmEvt) { /* initialize control block before handling event */ pCcb->handle = pDmEvt->connOpen.handle; - pCcb->mtu = ATT_DEFAULT_MTU; pCcb->connId = (dmConnId_t) pDmEvt->hdr.param; - pCcb->control = 0; + + for (i = 0; i < ATT_BEARER_MAX; i++) + { + pCcb->sccb[i].mtu = ATT_DEFAULT_MTU; + pCcb->sccb[i].control = 0; + } + pCcb->pPendDbHashRsp = NULL; } @@ -185,6 +203,12 @@ static void attDmConnCback(dmEvt_t *pDmEvt) } } + /* pass DM event to EATT */ + if (attCb.eattDmCback != NULL) + { + (*attCb.eattDmCback)(pDmEvt); + } + /* execute ATT connection callback */ if (attCb.connCback != NULL) { @@ -221,6 +245,22 @@ void attEmptyConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) return; } +/*************************************************************************************************/ +/*! + * \brief Empty l2c coc callback for ATT. + * + * \param handle The connection handle. + * \param len The length of the L2CAP payload data in pPacket. + * \param pPacket A buffer containing the packet. + * + * \return None. + */ +/*************************************************************************************************/ +void attEmptyL2cCocCback(l2cCocEvt_t *pMsg) +{ + return; +} + /*************************************************************************************************/ /*! * \brief Empty data callback for ATT. @@ -303,7 +343,7 @@ bool_t attUuidCmp16to128(const uint8_t *pUuid16, const uint8_t *pUuid128) * \return None. */ /*************************************************************************************************/ -void attSetMtu(attCcb_t *pCcb, uint16_t peerMtu, uint16_t localMtu) +void attSetMtu(attCcb_t *pCcb, uint8_t slot, uint16_t peerMtu, uint16_t localMtu) { uint16_t mtu; @@ -311,10 +351,10 @@ void attSetMtu(attCcb_t *pCcb, uint16_t peerMtu, uint16_t localMtu) mtu = WSF_MIN(peerMtu, localMtu); /* if current mtu is not the same as the negotiated value */ - if (pCcb->mtu != mtu) + if (pCcb->sccb[slot].mtu != mtu) { /* set mtu to the new value */ - pCcb->mtu = mtu; + pCcb->sccb[slot].mtu = mtu; /* notify app about the new value */ attExecCallback(pCcb->connId, ATT_MTU_UPDATE_IND, 0, ATT_SUCCESS, mtu); @@ -366,6 +406,67 @@ void *attMsgAlloc(uint16_t len) return WsfMsgDataAlloc(len, HCI_TX_DATA_TAILROOM); } +/*************************************************************************************************/ +/*! + * \brief Send an L2CAP data packet on the given CID. + * + * \param pCcb ATT control block. + * \param slot EATT channel slot. + * \param handle The connection handle. The client receives this handle from DM. + * \param len The length of the payload data in pPacket. + * \param pPacket A buffer containing the packet. + * + * \return None. + */ +/*************************************************************************************************/ +void attL2cDataReq(attCcb_t *pCcb, uint8_t slot, uint16_t len, uint8_t *pPacket) +{ + if (slot == ATT_BEARER_SLOT_ID) + { + /* send packet to L2CAP via ATT channel */ + L2cDataReq(L2C_CID_ATT, pCcb->handle, len, pPacket); + } + else if (attCb.eattL2cDataReq) + { + attCb.eattL2cDataReq(pCcb, slot, len, pPacket); + } + else + { + WsfMsgFree(pPacket); + } +} + +/*************************************************************************************************/ +/*! + * \brief Encode a message parameter with the conn ID and the slot ID. + * + * \param chanId DM connection ID. + * \param slot EATT channel slot. + * + * \return param value. + */ +/*************************************************************************************************/ +uint16_t attMsgParam(dmConnId_t connId, uint8_t slot) +{ + return connId * (ATT_BEARER_MAX) + slot; +} + +/*************************************************************************************************/ +/*! + * \brief Decode a message parameter with the conn ID and the slot ID. + * + * \param chanId DM connection ID. + * \param slot EATT channel slot. + * + * \return None. + */ +/*************************************************************************************************/ +void attDecodeMsgParam(uint16_t param, dmConnId_t *pConnId, uint8_t *pSlot) +{ + *pSlot = (uint8_t) (param % (ATT_BEARER_MAX)); + *pConnId = param / (ATT_BEARER_MAX); +} + /*************************************************************************************************/ /*! * \brief ATT handler init function called during system initialization. @@ -383,6 +484,8 @@ void AttHandlerInit(wsfHandlerId_t handlerId) /* initialize control block */ attCb.pClient = &attFcnDefault; attCb.pServer = &attFcnDefault; + attCb.pEnServer = &eattFcnDefault; + attCb.pEnClient = &eattFcnDefault; /* Register with L2C */ L2cRegister(L2C_CID_ATT, attL2cDataCback, attL2cCtrlCback); @@ -407,7 +510,24 @@ void AttHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) /* Handle message */ if (pMsg != NULL) { - if (pMsg->event >= ATTS_MSG_START) + if (pMsg->event >= EATT_MSG_START) + { + if (attCb.eattHandler) + { + attCb.eattHandler(pMsg); + } + } + else if (pMsg->event >= EATTS_MSG_START) + { + /* pass event to server */ + (*attCb.pEnServer->msgCback)(pMsg); + } + else if (pMsg->event >= EATTC_MSG_START) + { + /* pass event to server */ + (*attCb.pEnClient->msgCback)(pMsg); + } + else if (pMsg->event >= ATTS_MSG_START) { /* pass event to server */ (*attCb.pServer->msgCback)(pMsg); @@ -472,7 +592,7 @@ void AttConnRegister(dmCback_t cback) /*************************************************************************************************/ uint16_t AttGetMtu(dmConnId_t connId) { - return (attCcbByConnId(connId)->mtu); + return (attCcbByConnId(connId)->sccb[ATT_BEARER_SLOT_ID].mtu); } /*************************************************************************************************/ @@ -532,7 +652,8 @@ void AttMsgFree(void *pMsg, uint8_t opcode) { uint8_t hdrLen; - WSF_ASSERT((opcode == ATT_PDU_VALUE_IND) || (opcode == ATT_PDU_VALUE_NTF)); + WSF_ASSERT((opcode == ATT_PDU_VALUE_IND) || (opcode == ATT_PDU_VALUE_NTF) || \ + (opcode == ATT_PDU_READ_MULT_VAR_RSP)); switch (opcode) { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.h index 67c4924efc0..cdb6f524ba7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_MAIN_H @@ -53,7 +55,8 @@ extern "C" { #define ATT_METHOD_VALUE_NTF 13 /* Handle value notification */ #define ATT_METHOD_VALUE_IND 14 /* Handle value indication */ #define ATT_METHOD_VALUE_CNF 15 /* Handle value confirm */ -#define ATT_METHOD_SIGNED_WRITE_CMD 16 /* Signed write command */ +#define ATT_METHOD_READ_MULT_VAR 16 /* Read multiple variable length */ +#define ATT_METHOD_SIGNED_WRITE_CMD 17 /* Signed write command */ /* Convert opcode to method */ #define ATT_OPCODE_2_METHOD(op) (((op) & ~ATT_PDU_MASK_SERVER) / 2) @@ -61,16 +64,27 @@ extern "C" { /* Client and server message macros */ #define ATTC_MSG_START 0x00 #define ATTS_MSG_START 0x20 -#define ATT_MSG_MASK(msg) ((msg) & 0x1F) +#define EATTC_MSG_START 0x40 +#define EATTS_MSG_START 0x60 +#define EATT_MSG_START 0x80 /* Buffer lengths for messages */ #define ATT_VALUE_IND_NTF_BUF_LEN (ATT_VALUE_NTF_LEN + L2C_PAYLOAD_START) +#define ATT_MULT_VALUE_NTF_BUF_LEN (ATT_PDU_MULT_VALUE_NTF_LEN + L2C_PAYLOAD_START) /* attCcb_t control bits */ #define ATT_CCB_STATUS_MTU_SENT (1<<0) /* MTU req or rsp sent */ #define ATT_CCB_STATUS_FLOW_DISABLED (1<<1) /* Data flow disabled */ #define ATT_CCB_STATUS_TX_TIMEOUT (1<<2) /* ATT transaction timed out */ #define ATT_CCB_STATUS_RSP_PENDING (1<<3) /* ATTS write rsp pending */ +#define ATT_CCB_STATUS_CNF_PENDING (1<<4) /* ATTC confirm pending */ + +/* Number of ATT bearers */ +#define ATT_BEARER_MAX (EATT_CONN_CHAN_MAX + 1) + +/* Single ATT bearer slot ID */ +#define ATT_BEARER_SLOT_ID 0 +#define ATT_BEARER_SLOT_INVALID 0xff /************************************************************************************************** Data Types @@ -82,16 +96,20 @@ typedef struct uint16_t handle; /* Attribute handle of pending response. */ } attPendDbHashRsp_t; +/* Bearer slot control block */ +typedef struct +{ + uint16_t mtu; /* connection mtu */ + uint8_t control; /* Control bitfield */ +} attSccb_t; + /* Connection control block */ typedef struct { - wsfQueue_t prepWriteQueue; /* prepare write queue */ - wsfTimer_t idleTimer; /* service discovery idle timer */ - uint16_t handle; /* connection handle */ - uint16_t mtu; /* connection mtu */ - dmConnId_t connId; /* DM connection ID */ - uint8_t control; /* Control bitfield */ - attPendDbHashRsp_t *pPendDbHashRsp; /* Pending ATT Response information. */ + attSccb_t sccb[ATT_BEARER_MAX]; /* Bearer slot control blocks */ + uint16_t handle; /* connection handle */ + dmConnId_t connId; /* DM connection ID */ + attPendDbHashRsp_t *pPendDbHashRsp; /* Pending ATT Response information. */ } attCcb_t; /* ATT message handling function type */ @@ -100,6 +118,12 @@ typedef void (*attMsgHandler_t)(void *pMsg); /* ATT connection callback type */ typedef void (*attConnCback_t)(attCcb_t *pCcb, dmEvt_t *pDmEvt); +/* EATT event hamdler callback type */ +typedef void (*eattEventCback_t)(wsfMsgHdr_t *pMsg); + +/* EATT L2C COC data request function type */ +typedef void (*eattL2cDataReq_t)(attCcb_t *pCcb, uint8_t slot, uint16_t len, uint8_t *pPacket); + /* Callback interface for client and server */ typedef struct { @@ -109,12 +133,26 @@ typedef struct attConnCback_t connCback; /* Connection callback */ } attFcnIf_t; +/* Callback interface for enhanced client and server */ +typedef struct +{ + l2cCocCback_t l2cCocData; /* L2CAP COC data indication callback */ + l2cCocCback_t l2cCocCnf; /* L2CAP COC data confirm callback */ + attMsgHandler_t msgCback; /* Message handling callback */ + attConnCback_t connCback; /* Connection callback */ +} eattFcnIf_t; + /* Main control block of the ATT subsystem */ typedef struct { attCcb_t ccb[DM_CONN_MAX]; /* Connection control blocks */ attFcnIf_t const *pClient; /* Client callback interface */ attFcnIf_t const *pServer; /* Server callback interface */ + eattFcnIf_t const *pEnServer; /* Enhanced Server callback interface */ + eattFcnIf_t const *pEnClient; /* Enhanced Client callback interface */ + eattEventCback_t eattHandler; /* Enhanced ATT event callback */ + dmCback_t eattDmCback; /* Enhanced ATT DM callback */ + eattL2cDataReq_t eattL2cDataReq; /* Enhanced ATT L2C COC data request function */ attCback_t cback; /* ATT callback function */ dmCback_t connCback; /* ATT connection callback function */ wsfHandlerId_t handlerId; /* WSF handler ID */ @@ -138,15 +176,20 @@ extern attCb_t attCb; void attEmptyHandler(wsfMsgHdr_t *pMsg); void attEmptyDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket); void attEmptyConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt); +void attEmptyL2cCocCback(l2cCocEvt_t *pMsg); attCcb_t *attCcbByHandle(uint16_t handle); attCcb_t *attCcbByConnId(dmConnId_t connId); bool_t attUuidCmp16to128(const uint8_t *pUuid16, const uint8_t *pUuid128); -void attSetMtu(attCcb_t *pCcb, uint16_t peerMtu, uint16_t localMtu); +void attSetMtu(attCcb_t *pCcb, uint8_t slot, uint16_t peerMtu, uint16_t localMtu); void attExecCallback(dmConnId_t connId, uint8_t event, uint16_t handle, uint8_t status, uint16_t mtu); void *attMsgAlloc(uint16_t len); +void attL2cDataReq(attCcb_t *pCcb, uint8_t slot, uint16_t len, uint8_t *pPacket); +uint16_t attMsgParam(dmConnId_t connId, uint8_t slot); +void attDecodeMsgParam(uint16_t param, dmConnId_t *pConnId, uint8_t *pSlot); + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_sign.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_sign.h index 9f4fd3b4d98..30b6e5dad7e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_sign.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_sign.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT optional signed PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT optional signed PDU processing functions. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATT_SIGN_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_uuid.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_uuid.c index d34e556fd14..52cda51039c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_uuid.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/att_uuid.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT UUID constants. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT UUID constants. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -53,6 +55,8 @@ const uint8_t attPlxsSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_PUL const uint8_t attUdsSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_USER_DATA_SERVICE)}; const uint8_t attMprvSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MESH_PRV_SERVICE)}; const uint8_t attMprxSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MESH_PROXY_SERVICE)}; +const uint8_t attWssSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_WEIGHT_SCALE_SERVICE)}; +const uint8_t attCteSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CONSTANT_TONE_SERVICE)}; /*! GATT UUIDs */ const uint8_t attPrimSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_PRIMARY_SERVICE)}; @@ -174,15 +178,14 @@ const uint8_t attMprvDinChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MES const uint8_t attMprvDoutChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MESH_PRV_DATA_OUT)}; const uint8_t attMprxDinChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MESH_PROXY_DATA_IN)}; const uint8_t attMprxDoutChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_MESH_PROXY_DATA_OUT)}; -const uint8_t attWssSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_WEIGHT_SCALE_SERVICE)}; const uint8_t attWmChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_WEIGHT_MEAS)}; const uint8_t attWsfChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_WEIGHT_SCALE_FEATURE)}; const uint8_t attGattCsfChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CLIENT_SUPPORTED_FEATURES)}; const uint8_t attGattDbhChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_DATABASE_HASH)}; -const uint8_t attCteSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CONSTANT_TONE_SERVICE)}; const uint8_t attCteEnChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_ENABLE)}; const uint8_t attCteMinLenChUuid[ATT_16_UUID_LEN] ={UINT16_TO_BYTES(ATT_UUID_CTE_MIN_LEN)}; const uint8_t attCteTxCntChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_TX_CNT)}; const uint8_t attCteTxDurChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_TX_DURATION)}; const uint8_t attCteIntChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_INTERVAL)}; const uint8_t attCtePhyChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_CTE_PHY)}; +const uint8_t attSsfChUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_SERVER_SUPPORTED_FEATURES)}; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_disc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_disc.c index 19a30c34302..ebb7e5658db 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_disc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_disc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief ATT client service and characteristic utility functions. + * \file + * + * \brief ATT client service and characteristic utility functions. + * + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,6 +46,10 @@ #define ATT_READ_RSP_LEN_UUID16 (ATT_CHAR_DECL_LEN_UUID16 + 2) #define ATT_READ_RSP_LEN_UUID128 (ATT_CHAR_DECL_LEN_UUID128 + 2) +/* Read by type response lengths for service include discovery */ +#define ATT_READ_RSP_INC_LEN_UUID16 (ATT_16_UUID_LEN + 6) +#define ATT_READ_RSP_INC_LEN_UUID128 (ATT_128_UUID_LEN + 6) + /* Find info response lengths */ #define ATT_FIND_RSP_LEN_UUID16 (ATT_16_UUID_LEN + 2) #define ATT_FIND_RSP_LEN_UUID128 (ATT_128_UUID_LEN + 2) @@ -292,7 +298,7 @@ static uint8_t attcDiscProcDesc(attcDiscCb_t *pCb, attEvt_t *pMsg) } /* if descriptor discovery complete for this characteristic */ - if (pMsg->hdr.status != ATT_SUCCESS || pMsg->continuing == FALSE) + if ((pMsg->hdr.status != ATT_SUCCESS) || (pMsg->continuing == FALSE)) { /* go to next entry in list */ pChar = &pCb->pCharList[pCb->charListIdx]; @@ -327,9 +333,7 @@ static uint8_t attcDiscProcDesc(attcDiscCb_t *pCb, attEvt_t *pMsg) * \param settings Indicates 16 or 128 bit UUID. * \param pDecl Pointer to declaration. * - * \return ATT_CONTINUING if successful and discovery procedure is continuing. - * ATT_SUCCESS if discovery procedure completed successfully. - * Otherwise the discovery procedure failed. + * \return none. */ /*************************************************************************************************/ static void attcDiscProcCharDecl(attcDiscCb_t *pCb, uint8_t settings, uint8_t *pDecl) @@ -381,6 +385,7 @@ static void attcDiscProcCharDecl(attcDiscCb_t *pCb, uint8_t settings, uint8_t *p } ATT_TRACE_INFO1("characteristic found handle:0x%x", hdl); + break; } } } @@ -446,7 +451,7 @@ static uint8_t attcDiscProcChar(attcDiscCb_t *pCb, attEvt_t *pMsg) } /* if characteristic discovery complete */ - if (pMsg->hdr.status != ATT_SUCCESS || pMsg->continuing == FALSE) + if ((pMsg->hdr.status != ATT_SUCCESS) || (pMsg->continuing == FALSE)) { /* check if characteristic end handle needs to be set */ if (pCb->endHdlIdx != ATT_DISC_HDL_IDX_NONE) @@ -513,6 +518,55 @@ static uint8_t attcDiscConfigNext(dmConnId_t connId, attcDiscCb_t *pCb) return ATT_SUCCESS; } +/*************************************************************************************************/ +/*! + * \brief Process an included service. + * + * \param pCb Pointer to service discovery control block. + * \param settings Indicates 16 or 128 bit UUID. + * \param pDecl Pointer to declaration. + * + * \return none. + */ +/*************************************************************************************************/ +static void attcDiscProcIncSvc(attcDiscCb_t *pCb, uint8_t settings, uint8_t *pDecl) +{ + attcDiscChar_t **pChar; + uint16_t handle; + uint8_t i; + + /* parse it */ + BSTREAM_TO_UINT16(handle, pDecl); + pDecl += 4; /* skip start/end handle */ + + /* check handle */ + if ((handle >= pCb->svcStartHdl) && handle <= (pCb->svcEndHdl)) + { + /* now pDecl points to UUID; search for UUID in characteristic list */ + for (i = 0, pChar = pCb->pCharList; i < pCb->charListLen; i++, pChar++) + { + /* if characteristic not already found */ + if (pCb->pHdlList[i] == 0) + { + /* if UUIDs match */ + if (attcUuidCmp(*pChar, pDecl, settings)) + { + /* match found; store handle */ + pCb->pHdlList[i] = handle; + + ATT_TRACE_INFO1("service include found handle:0x%x", handle); + return; + } + } + } + } + else + { + /* invalid handle; skip this declaration */ + ATT_TRACE_WARN1("invalid handle:0x%x", handle); + } +} + /*************************************************************************************************/ /*! * \brief This utility function discovers the given service on a peer device. Function @@ -635,7 +689,7 @@ uint8_t AttcDiscCharCmpl(attcDiscCb_t *pCb, attEvt_t *pMsg) } /* if characteristic discovery failed clear any handles */ - if (status != ATT_SUCCESS && status != ATT_CONTINUING) + if ((status != ATT_SUCCESS) && (status != ATT_CONTINUING)) { memset(pCb->pHdlList, 0, (pCb->charListLen * sizeof(uint16_t))); } @@ -643,6 +697,105 @@ uint8_t AttcDiscCharCmpl(attcDiscCb_t *pCb, attEvt_t *pMsg) return status; } +/*************************************************************************************************/ +/*! + * \brief This utility function starts included service discovery for a service on a peer device. + * The service must have been previously discovered by calling AttcDiscService() and +* AttcDiscServiceCmpl(). + * + * \param connId DM connection ID. + * \param pCb Pointer to service discovery control block. + * + * \return None. + */ +/*************************************************************************************************/ +void AttcDiscIncSvcStart(dmConnId_t connId, attcDiscCb_t *pCb) +{ + /* initialize control block */ + pCb->charListIdx = 0; + pCb->endHdlIdx = ATT_DISC_HDL_IDX_NONE; + + AttcReadByTypeReq(connId, pCb->svcStartHdl, pCb->svcEndHdl, ATT_16_UUID_LEN, + (uint8_t *) attIncUuid, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief This utility function processes a service include discovery result. It should be + * called when an ATTC_READ_BY_TYPE_RSP allback event is received after service include + * discovery is initiated by calling AttcDiscIncSvcStart(). + * + * \param pCb Pointer to service discovery control block. + * \param pMsg ATT callback event message. + * + * \return ATT_CONTINUING if successful and discovery procedure is continuing. + * ATT_SUCCESS if discovery procedure completed successfully. + * Otherwise the discovery procedure failed. + */ +/*************************************************************************************************/ +uint8_t AttcDiscIncSvcCmpl(attcDiscCb_t *pCb, attEvt_t *pMsg) +{ + uint8_t *p; + uint8_t *pEnd; + uint8_t pairLen; + uint8_t settings; + + /* verify callback event */ + if (pMsg->hdr.event != ATTC_READ_BY_TYPE_RSP) + { + ATT_TRACE_WARN1("unexpected callback event %d", pMsg->hdr.event); + return ATT_ERR_UNDEFINED; + } + + /* if read by type successful */ + if (pMsg->hdr.status == ATT_SUCCESS) + { + p = pMsg->pValue; + pEnd = pMsg->pValue + pMsg->valueLen; + + /* verify attribute-handle pair length and determine UUID length */ + BSTREAM_TO_UINT8(pairLen, p); + if (pairLen == ATT_READ_RSP_INC_LEN_UUID16) + { + settings = 0; + } + else if (pairLen == ATT_READ_RSP_INC_LEN_UUID128) + { + settings = ATTC_SET_UUID_128; + } + else + { + return ATT_ERR_INVALID_RSP; + } + + /* for each characteristic declaration */ + while (p < pEnd) + { + /* process service include */ + attcDiscProcIncSvc(pCb, settings, p); + + /* go to next */ + p += pairLen; + } + } + + /* if include discovery complete */ + if ((pMsg->hdr.status != ATT_SUCCESS) || (pMsg->continuing == FALSE)) + { + /* check if characteristic end handle needs to be set */ + if (pCb->endHdlIdx != ATT_DISC_HDL_IDX_NONE) + { + /* end handle of characteristic declaration is end handle of service */ + pCb->pHdlList[pCb->endHdlIdx] = pCb->svcEndHdl; + } + + return ATT_SUCCESS; + } + + /* still more to do */ + return ATT_CONTINUING; +} + /*************************************************************************************************/ /*! * \brief This utility function starts characteristic configuration for characteristics on a diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_eatt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_eatt.c new file mode 100644 index 00000000000..45305ddb59e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_eatt.c @@ -0,0 +1,817 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Enhanced ATT (EATT) client module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_timer.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_os.h" +#include "util/bstream.h" +#include "l2c_api.h" +#include "l2c_main.h" +#include "dm_api.h" +#include "eatt_api.h" +#include "att_eatt.h" +#include "att_api.h" +#include "att_defs.h" +#include "att_main.h" +#include "attc_main.h" + +/************************************************************************************************** + Function Prototypes +**************************************************************************************************/ + +static void eattcL2cCocDataInd(l2cCocEvt_t *pEvt); +static void eattcL2cCocDataCnf(l2cCocEvt_t *pEvt); +static void eattcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/* Interface to ATT */ +static const eattFcnIf_t attcFcnIf = +{ + eattcL2cCocDataInd, + eattcL2cCocDataCnf, + (attMsgHandler_t) attcMsgCback, + eattcConnCback +}; + +/*************************************************************************************************/ +/*! + * \brief Get a channel for transmission of an EATT client message. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param dataLen Length of value data. + * + * \return Slot ID + */ +/*************************************************************************************************/ +static uint8_t eattcGetFreeSlot(dmConnId_t connId, uint8_t priority, uint16_t dataLen) +{ + eattConnCb_t *pEattCcb = eattGetConnCb(connId); + + if (pEattCcb) + { + uint8_t i; + + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + attcCcb_t *pCcb; + uint8_t slot = i + 1; + + if ((pCcb = attcCcbByConnId(connId, slot))) + { + eattChanCb_t *pChanCb = &pEattCcb->pChanCb[i]; + + if (pChanCb->inUse && (pChanCb->priority >= priority) && (pChanCb->localMtu >= dataLen)) + { + if (pCcb->outReq.hdr.event == ATTC_MSG_API_NONE) + { + EATT_TRACE_INFO1("eattcGetFreeSlot: allocating slot: %#x", slot); + return slot; + } + } + } + } + } + + return ATT_BEARER_SLOT_ID; +} + +/*************************************************************************************************/ +/*! + * \brief L2CAP CoC data indication callback function. + * + * \param pEvt Pointer to event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattcL2cCocDataInd(l2cCocEvt_t *pEvt) +{ + l2cCocDataInd_t *pDataInd = &pEvt->dataInd; + uint8_t opcode; + attcCcb_t *pCcb; + dmConnId_t connId = (dmConnId_t) pDataInd->hdr.param; + uint8_t slot = eattGetSlotId(connId, pDataInd->cid); + + if (slot != ATT_BEARER_SLOT_INVALID) + { + /* get connection control block, ignore packet if not found */ + if ((pCcb = attcCcbByConnId(connId, slot)) == NULL) + { + return; + } + + /* parse opcode */ + opcode = *pDataInd->pData; + + /* if response */ + if ((opcode <= ATT_PDU_EXEC_WRITE_RSP) || (opcode == ATT_PDU_READ_MULT_VAR_RSP)) + { + attcProcRsp(pCcb, pDataInd->dataLen, pDataInd->pData - L2C_PAYLOAD_START); + } + /* else if indication or notification */ + else if ((opcode == ATT_PDU_VALUE_NTF) || (opcode == ATT_PDU_VALUE_IND)) + { + attcProcInd(pCcb, pDataInd->dataLen, pDataInd->pData - L2C_PAYLOAD_START); + } + /* else if multiple value notification */ + else if (opcode == ATT_PDU_MULT_VALUE_NTF) + { + attcProcMultiVarNtf(pCcb, pDataInd->dataLen, pDataInd->pData - L2C_PAYLOAD_START); + } + /* else unknown opcode */ + else + { + ATT_TRACE_WARN1("eattc unknown opcode 0x%02x", opcode); + } + } + else + { + ATT_TRACE_WARN0("eattc unexpected data indication"); + } +} + +/*************************************************************************************************/ +/*! + * \brief L2CAP CoC data confirm callback function. + * + * \param pEvt Pointer to event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattcL2cCocDataCnf(l2cCocEvt_t *pEvt) +{ + l2cCocDataCnf_t *pDataCnf = &pEvt->dataCnf; + attcCcb_t *pCcb; + dmConnId_t connId = (dmConnId_t) pDataCnf->hdr.param; + uint8_t slot = eattGetSlotId(connId, pDataCnf->cid); + + if (slot != ATT_BEARER_SLOT_INVALID) + { + if (pDataCnf->hdr.status == L2C_COC_DATA_SUCCESS) + { + /* get CCB */ + if ((pCcb = attcCcbByConnId(connId, slot)) != NULL) + { + /* if confirmation pending try sending now */ + EattcIndConfirm(connId, pDataCnf->cid); + + /* call pending write command callback */ + attcWriteCmdCallback(connId, pCcb, ATT_SUCCESS); + } + } + else + { + /* TBD: handle error case */ + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Connection callback for ATTC. + * + * \param pCcb ATT control block. + * \param pDmEvt DM callback event. + * + * \return None. + */ +/*************************************************************************************************/ +void eattcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) +{ + /* take no action */ +} + +/*************************************************************************************************/ +/*! + * \brief Build and send a WSF message to ATTC. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param msgId Message ID. + * \param pPkt Packet parameters. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void eattcSendMsg(dmConnId_t connId, uint8_t priority, uint16_t handle, uint8_t msgId, + attcPktParam_t *pPkt, bool_t continuing) +{ + uint8_t slot; + uint16_t dataLen = 0; + + /* if packet is not null then find out its length */ + if (pPkt != NULL) + { + /* if not prepare write request */ + if (msgId != ATTC_MSG_API_PREP_WRITE) + { + dataLen = pPkt->len; + } + /* else prepare write request */ + else + { + /* if not continuing */ + if (!continuing) + { + /* single prepare write request */ + dataLen = ATT_PREP_WRITE_REQ_LEN + pPkt->pW->len; + } + /* else will be sent as multiple prepare write requests */ + } + } + + /* get the next available channel given the priority and data length */ + slot = eattcGetFreeSlot(connId, priority, dataLen); + + /* if a cid is available */ + if (slot) + { + attcApiMsg_t *pMsg; + + /* allocate message buffer */ + if ((pMsg = WsfMsgAlloc(sizeof(attcApiMsg_t))) != NULL) + { + EATT_TRACE_INFO2("eattcSendMsg: sending event: %#x slot: %#x", msgId, slot); + + /* set parameters */ + pMsg->hdr.param = connId; + pMsg->hdr.status = continuing; + pMsg->hdr.event = msgId; + pMsg->pPkt = pPkt; + pMsg->handle = handle; + pMsg->slot = slot; + + /* send message */ + WsfMsgSend(attCb.handlerId, pMsg); + } + } + else + { + /* no EATT slot, pass to ATT */ + attcSendMsg(connId, handle, msgId, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Find Information Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcFindInfoReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_FIND_INFO_REQ_BUF_LEN)) != NULL) + { + /* set parameters */ + pPkt->len = ATT_FIND_INFO_REQ_LEN; + pPkt->h.startHandle = startHandle; + pPkt->h.endHandle = endHandle; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_FIND_INFO_REQ); + + /* send message */ + eattcSendMsg(connId, priority, startHandle, ATTC_MSG_API_FIND_INFO, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Find By Type Value Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuid16 16-bit UUID to find. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcFindByTypeValueReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint16_t uuid16, uint16_t valueLen, uint8_t *pValue, bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_FIND_TYPE_REQ_BUF_LEN + valueLen)) != NULL) + { + /* set parameters */ + pPkt->len = ATT_FIND_TYPE_REQ_LEN + valueLen; + pPkt->h.startHandle = startHandle; + pPkt->h.endHandle = endHandle; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_FIND_TYPE_REQ); + /* skip start and end handle fields */ + p += (2 * sizeof(uint16_t)); + UINT16_TO_BSTREAM(p, uuid16); + memcpy(p, pValue, valueLen); + + /* send message */ + eattcSendMsg(connId, priority, startHandle, ATTC_MSG_API_FIND_BY_TYPE_VALUE, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read By Type Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuidLen Length of UUID (2 or 16). + * \param pUuid Pointer to UUID data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadByTypeReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint8_t uuidLen, uint8_t *pUuid, bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_READ_TYPE_REQ_BUF_LEN + uuidLen)) != NULL) + { + /* set parameters */ + pPkt->len = ATT_READ_TYPE_REQ_LEN + uuidLen; + pPkt->h.startHandle = startHandle; + pPkt->h.endHandle = endHandle; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_TYPE_REQ); + /* skip start and end handle fields */ + p += (2 * sizeof(uint16_t)); + memcpy(p, pUuid, uuidLen); + + /* send message */ + eattcSendMsg(connId, priority, startHandle, ATTC_MSG_API_READ_BY_TYPE, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadReq(dmConnId_t connId, uint8_t priority, uint16_t handle) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_READ_REQ_BUF_LEN)) != NULL) + { + /* set length */ + pPkt->len = ATT_READ_REQ_LEN; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_REQ); + UINT16_TO_BSTREAM(p, handle); + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_READ, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param offset Read attribute data starting at this offset. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadLongReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t offset, bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_READ_BLOB_REQ_BUF_LEN)) != NULL) + { + /* set parameters */ + pPkt->len = ATT_READ_BLOB_REQ_LEN; + pPkt->o.offset = offset; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_BLOB_REQ); + UINT16_TO_BSTREAM(p, handle); + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_READ_LONG, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Multiple Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param numHandles Number of handles in attribute handle list. + * \param pHandles List of attribute handles. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadMultipleReq(dmConnId_t connId, uint8_t priority, uint8_t numHandles, uint16_t *pHandles) +{ + attcPktParam_t *pPkt; + uint8_t *p; + uint16_t handle; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_READ_MULT_REQ_BUF_LEN + (numHandles * sizeof(uint16_t)))) != NULL) + { + /* set length */ + pPkt->len = ATT_READ_MULT_REQ_LEN + (numHandles * sizeof(uint16_t)); + + /* save first handle */ + handle = pHandles[0]; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_MULT_REQ); + while (numHandles--) + { + UINT16_TO_BSTREAM(p, *pHandles); + pHandles++; + } + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_READ_MULTIPLE, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read By Group Type Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param startHandle Attribute start handle. + * \param endHandle Attribute end handle. + * \param uuidLen Length of UUID (2 or 16). + * \param pUuid Pointer to UUID data. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadByGroupTypeReq(dmConnId_t connId, uint8_t priority, uint16_t startHandle, uint16_t endHandle, + uint8_t uuidLen, uint8_t *pUuid, bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_READ_GROUP_TYPE_REQ_BUF_LEN + uuidLen)) != NULL) + { + /* set parameters */ + pPkt->len = ATT_READ_GROUP_TYPE_REQ_LEN + uuidLen; + pPkt->h.startHandle = startHandle; + pPkt->h.endHandle = endHandle; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_GROUP_TYPE_REQ); + /* skip start and end handle fields */ + p += (2 * sizeof(uint16_t)); + memcpy(p, pUuid, uuidLen); + + /* send message */ + eattcSendMsg(connId, priority, startHandle, ATTC_MSG_API_READ_BY_GROUP_TYPE, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcWriteReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, uint8_t *pValue) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_WRITE_REQ_BUF_LEN + valueLen)) != NULL) + { + /* set length */ + pPkt->len = ATT_WRITE_REQ_LEN + valueLen; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_REQ); + UINT16_TO_BSTREAM(p, handle); + memcpy(p, pValue, valueLen); + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_WRITE, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Cancel an attribute protocol request in progress. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcCancelReq(dmConnId_t connId, uint8_t priority) +{ + eattcSendMsg(connId, priority, 0, ATTC_MSG_API_CANCEL, NULL, FALSE); +} + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol indication confirmation. + * + * \param connId DM connection ID. + * \param cid L2Cap channel ID. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcIndConfirm(dmConnId_t connId, uint16_t cid) +{ + uint8_t slot = eattGetSlotId(connId, cid); + attSccb_t *pSccb = &attCb.ccb[connId-1].sccb[slot]; + uint8_t cnfPkt[] = {ATT_PDU_VALUE_CNF}; + + if (slot != ATT_BEARER_SLOT_INVALID) + { + attcCcb_t *pCcb = attcCcbByHandle(connId - 1, slot); + + /* If confirmation is pending */ + if ((pCcb && pSccb->control & ATT_CCB_STATUS_CNF_PENDING) && + !(pSccb->control & ATT_CCB_STATUS_FLOW_DISABLED)) + { + pSccb->control &= ~ATT_CCB_STATUS_CNF_PENDING; + L2cCocDataReq(cid, ATT_VALUE_CNF_LEN, cnfPkt); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Write Command. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcWriteCmd(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, uint8_t *pValue) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_WRITE_CMD_BUF_LEN + valueLen)) != NULL) + { + /* set length */ + pPkt->len = ATT_WRITE_CMD_LEN + valueLen; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_CMD); + UINT16_TO_BSTREAM(p, handle); + memcpy(p, pValue, valueLen); + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_WRITE_CMD, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Prepare Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param offset Write attribute data starting at this offset. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * \param valueByRef TRUE if pValue data is accessed by reference rather than copied. + * \param continuing TRUE if ATTC continues sending requests until complete. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcPrepareWriteReq(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t offset, + uint16_t valueLen, uint8_t *pValue, bool_t valueByRef, bool_t continuing) +{ + attcPktParam_t *pPkt; + uint8_t *p; + uint16_t bufLen; + + if (continuing && valueByRef) + { + bufLen = ATT_PREP_WRITE_REQ_BUF_LEN; + } + else + { + bufLen = ATT_PREP_WRITE_REQ_BUF_LEN + valueLen; + } + + /* allocate packet and parameter buffer */ + if ((pPkt = attcPrepWriteAllocMsg(bufLen)) != NULL) + { + /* set parameters */ + pPkt->pW->len = valueLen; + pPkt->pW->offset = offset; + + /* build partial packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_PREP_WRITE_REQ); + UINT16_TO_BSTREAM(p, handle); + + /* skip over offset field */ + p += sizeof(uint16_t); + + /* set value pointer and copy data to packet, if not valueByRef */ + if (continuing && valueByRef) + { + pPkt->pW->pValue = pValue; + } + else + { + memcpy(p, pValue, valueLen); + pPkt->pW->pValue = p; + } + + /* send message */ + eattcSendMsg(connId, priority, handle, ATTC_MSG_API_PREP_WRITE, pPkt, continuing); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Execute Write Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param writeAll TRUE to write all queued writes, FALSE to cancel all queued writes. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcExecuteWriteReq(dmConnId_t connId, uint8_t priority, bool_t writeAll) +{ + attcPktParam_t *pPkt; + uint8_t *p; + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(ATT_EXEC_WRITE_REQ_BUF_LEN)) != NULL) + { + /* set length */ + pPkt->len = ATT_EXEC_WRITE_REQ_LEN; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_EXEC_WRITE_REQ); + UINT8_TO_BSTREAM(p, writeAll); + + /* send message */ + eattcSendMsg(connId, priority, 0, ATTC_MSG_API_EXEC_WRITE, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initiate an attribute protocol Read Multiple Variable Length Request. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param numHandles The number of handles in pHandles. + * \param pHandles List of attribute handles to read. + * + * \return None. + */ +/*************************************************************************************************/ +void EattcReadMultVarLenReq(dmConnId_t connId, uint8_t priority, uint8_t numHandles, uint16_t *pHandles) +{ + attcPktParam_t *pPkt; + uint8_t *p; + uint8_t msgLen = ATT_READ_MULT_VAR_REQ_LEN + (sizeof(uint16_t) * numHandles); + uint8_t i; + + WSF_ASSERT(numHandles >= 2) + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(L2C_PAYLOAD_START + msgLen)) != NULL) + { + /* set length */ + pPkt->len = msgLen; + + /* build packet */ + p = (uint8_t *) pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_MULT_VAR_REQ); + + for (i = 0; i < numHandles; i++) + { + UINT16_TO_BSTREAM(p, pHandles[i]); + } + + /* send message */ + eattcSendMsg(connId, priority, 0, ATTC_MSG_API_READ_MULT_VAR, pPkt, FALSE); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT Client. + * + * \return None + */ + /*************************************************************************************************/ +void EattcInit() +{ + /* set up callback interface */ + attCb.pEnClient = &attcFcnIf; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.c index 2f613d3f521..10cb08f29cd 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief ATT client main module. + * \file + * + * \brief ATT client main module. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -49,7 +51,9 @@ typedef void (*attcSendReq_t)(attcCcb_t *pCcb); static void attcDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket); static void attcCtrlCback(wsfMsgHdr_t *pMsg); static void attcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt); -static void attcMsgCback(attcApiMsg_t *pMsg); + +extern void attcMsgCback(attcApiMsg_t *pMsg); +extern void attcWriteCmdCallback(dmConnId_t connId, attcCcb_t *pCcb, uint8_t status); static void attcSendSimpleReq(attcCcb_t *pCcb); static void attcSendContinuingReq(attcCcb_t *pCcb); @@ -85,7 +89,11 @@ static const attcSendReq_t attcSendReqTbl[] = attcSendSimpleReq, /* ATTC_MSG_API_WRITE */ attcSendWriteCmd, /* ATTC_MSG_API_WRITE_CMD */ attcSendPrepWriteReq, /* ATTC_MSG_API_PREP_WRITE */ - attcSendSimpleReq /* ATTC_MSG_API_EXEC_WRITE */ + attcSendSimpleReq, /* ATTC_MSG_API_EXEC_WRITE */ + NULL, /* unused */ + NULL, /* unused */ + NULL, /* unused */ + attcSendSimpleReq /* ATTC_MSG_API_READ_MULT_VAR */ }; /************************************************************************************************** @@ -100,14 +108,14 @@ attcCb_t attcCb; * \brief Check if application callback is pending for a given write command, or the maximum * number of simultaneous write commands has been reached. * - * \param pCcb ATTC control block. - * \param pMsg ATTC message. + * \param pCcb ATTC control block. + * \param handle Connection handle. * * \return TRUE if app callback's pending or maximum number of simultaneous write commands reached. * FALSE, otherwise. */ /*************************************************************************************************/ -static bool_t attcPendWriteCmd(attcCcb_t *pCcb, attcApiMsg_t *pMsg) +bool_t attcPendWriteCmd(attcCcb_t *pCcb, uint16_t handle) { uint8_t pendRsp; uint8_t i; @@ -121,7 +129,7 @@ static bool_t attcPendWriteCmd(attcCcb_t *pCcb, attcApiMsg_t *pMsg) if (pCcb->pendWriteCmdHandle[i] != ATT_HANDLE_NONE) { /* if callback pending for this handle */ - if (pCcb->pendWriteCmdHandle[i] == pMsg->handle) + if (pCcb->pendWriteCmdHandle[i] == handle) { /* callback pending for this write command */ return TRUE; @@ -172,7 +180,7 @@ static void attcSetPendWriteCmd(attcCcb_t *pCcb) * \return None. */ /*************************************************************************************************/ -static void attcWriteCmdCallback(dmConnId_t connId, attcCcb_t *pCcb, uint8_t status) +void attcWriteCmdCallback(dmConnId_t connId, attcCcb_t *pCcb, uint8_t status) { uint8_t i; @@ -212,7 +220,7 @@ static void attcSendSimpleReq(attcCcb_t *pCcb) } /* send packet to L2CAP */ - L2cDataReq(L2C_CID_ATT, pCcb->pMainCcb->handle, pPkt->len, (uint8_t *) pPkt); + attL2cDataReq(pCcb->pMainCcb, pCcb->outReq.slot, pPkt->len, (uint8_t *) pPkt); } /*************************************************************************************************/ @@ -242,7 +250,7 @@ static void attcSendContinuingReq(attcCcb_t *pCcb) else { /* free stored packet and call callback with failure status */ - attcReqClear(pCcb, &pCcb->outReq, ATT_ERR_MEMORY); + attcReqClear(pCcb->connId, &pCcb->outReq, ATT_ERR_MEMORY); return; } } @@ -279,7 +287,7 @@ static void attcSendContinuingReq(attcCcb_t *pCcb) WsfTimerStartSec(&pCcb->outReqTimer, pAttCfg->transTimeout); /* send packet to L2CAP */ - L2cDataReq(L2C_CID_ATT, pCcb->pMainCcb->handle, pPkt->len, (uint8_t *) pPkt); + attL2cDataReq(pCcb->pMainCcb, pCcb->outReq.slot, pPkt->len, (uint8_t *) pPkt); } /*************************************************************************************************/ @@ -294,7 +302,7 @@ static void attcSendContinuingReq(attcCcb_t *pCcb) static void attcSendMtuReq(attcCcb_t *pCcb) { /* if MTU already exchanged */ - if (pCcb->pMainCcb->control & ATT_CCB_STATUS_MTU_SENT) + if (pCcb->pMainCcb->sccb[pCcb->outReq.slot].control & ATT_CCB_STATUS_MTU_SENT) { /* discard request */ attcFreePkt(&pCcb->outReq); @@ -307,7 +315,7 @@ static void attcSendMtuReq(attcCcb_t *pCcb) else { /* set MTU sent */ - pCcb->pMainCcb->control |= ATT_CCB_STATUS_MTU_SENT; + pCcb->pMainCcb->sccb[pCcb->outReq.slot].control |= ATT_CCB_STATUS_MTU_SENT; /* send packet */ attcSendSimpleReq(pCcb); @@ -329,7 +337,7 @@ static void attcSendWriteCmd(attcCcb_t *pCcb) attcSendSimpleReq(pCcb); /* if flow not disabled */ - if (!(pCcb->pMainCcb->control & ATT_CCB_STATUS_FLOW_DISABLED)) + if (!(pCcb->pMainCcb->sccb[pCcb->outReq.slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) { /* call callback */ attcExecCallback(pCcb->pMainCcb->connId, ATTC_WRITE_CMD_RSP, pCcb->outReq.handle, ATT_SUCCESS); @@ -358,18 +366,19 @@ static void attcSendPrepWriteReq(attcCcb_t *pCcb) attcPktParam_t *pPkt; uint8_t *p; uint16_t dataLen; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* if continuing */ if (pCcb->outReq.hdr.status == ATTC_CONTINUING) { /* determine size of buffer to allocate */ - if (pCcb->outReqParams.w.len < (pCcb->pMainCcb->mtu - ATT_PREP_WRITE_REQ_LEN)) + if (pCcb->outReqParams.w.len < (mtu - ATT_PREP_WRITE_REQ_LEN)) { dataLen = pCcb->outReqParams.w.len; } else { - dataLen = pCcb->pMainCcb->mtu - ATT_PREP_WRITE_REQ_LEN; + dataLen = mtu - ATT_PREP_WRITE_REQ_LEN; } /* allocate new buffer */ @@ -390,7 +399,7 @@ static void attcSendPrepWriteReq(attcCcb_t *pCcb) else { /* free stored packet and call callback with failure status */ - attcReqClear(pCcb, &pCcb->outReq, ATT_ERR_MEMORY); + attcReqClear(pCcb->connId, &pCcb->outReq, ATT_ERR_MEMORY); return; } } @@ -418,7 +427,7 @@ static void attcSendPrepWriteReq(attcCcb_t *pCcb) WsfTimerStartSec(&pCcb->outReqTimer, pAttCfg->transTimeout); /* send packet to L2CAP */ - L2cDataReq(L2C_CID_ATT, pCcb->pMainCcb->handle, dataLen + ATT_PREP_WRITE_REQ_LEN, (uint8_t *) pPkt); + attL2cDataReq(pCcb->pMainCcb, pCcb->outReq.slot, dataLen + ATT_PREP_WRITE_REQ_LEN, (uint8_t *) pPkt); } /*************************************************************************************************/ @@ -451,7 +460,14 @@ void attcSetupReq(attcCcb_t *pCcb, attcApiMsg_t *pMsg) pCcb->outReq = *pMsg; /* store parameters */ - pCcb->outReqParams = *(pMsg->pPkt); + if (pMsg->hdr.event == ATTC_MSG_API_PREP_WRITE) + { + memcpy(&pCcb->outReqParams.w, pMsg->pPkt->pW, sizeof(attcPktParamPrepWrite_t)); + } + else + { + memcpy(&pCcb->outReqParams, pMsg->pPkt, sizeof(attcPktParam_t)); + } /* build and send request */ attcSendReq(pCcb); @@ -474,7 +490,7 @@ static void attcDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) attcCcb_t *pCcb; /* get connection control block for this handle, ignore packet if not found */ - if ((pCcb = attcCcbByHandle(handle)) == NULL) + if ((pCcb = attcCcbByHandle(handle, ATT_BEARER_SLOT_ID)) == NULL) { return; } @@ -492,6 +508,10 @@ static void attcDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) { attcProcInd(pCcb, len, pPacket); } + else if (opcode == ATT_PDU_MULT_VALUE_NTF) + { + attcProcMultiVarNtf(pCcb, len, pPacket); + } /* else unknown opcode */ else { @@ -515,7 +535,7 @@ static void attcCtrlCback(wsfMsgHdr_t *pMsg) /* note this function is currently only called when flow is enabled */ /* get CCB */ - if ((pCcb = attcCcbByConnId((dmConnId_t) pMsg->param)) != NULL) + if ((pCcb = attcCcbByConnId((dmConnId_t) pMsg->param, ATT_BEARER_SLOT_ID)) != NULL) { /* if confirmation pending try sending now */ AttcIndConfirm((dmConnId_t) pMsg->param); @@ -540,6 +560,7 @@ static void attcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) attcCcb_t *pClient; uint16_t localMtu; uint8_t status; + uint8_t i; /* if connection opened */ if (pDmEvt->hdr.event == DM_CONN_OPEN_IND) @@ -569,34 +590,37 @@ static void attcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) status = pDmEvt->connClose.hdr.status + ATT_HCI_ERR_BASE; } - /* get client control block directly */ - pClient = &attcCb.ccb[pCcb->connId - 1]; - - /* free any out req */ - if (pClient->outReq.hdr.event != ATTC_MSG_API_NONE) + /* free any req on deck */ + if (attcCb.onDeck[pCcb->connId].hdr.event != ATTC_MSG_API_NONE) { - WsfTimerStop(&pClient->outReqTimer); - attcReqClear(pClient, &pClient->outReq, status); + attcReqClear(pCcb->connId, &attcCb.onDeck[pCcb->connId], status); } - /* free any req on deck */ - if (pClient->onDeck.hdr.event != ATTC_MSG_API_NONE) + for (i = 0; i < ATT_BEARER_MAX; i++) { - attcReqClear(pClient, &pClient->onDeck, status); - } + /* get client control block directly */ + pClient = &attcCb.ccb[pCcb->connId - 1][i]; - /* initialize other control block variables */ - pClient->flowDisabled = FALSE; - pClient->cnfPending = FALSE; + /* free any out req */ + if (pClient->outReq.hdr.event != ATTC_MSG_API_NONE) + { + WsfTimerStop(&pClient->outReqTimer); + attcReqClear(pClient->connId, &pClient->outReq, status); + } - /* pass to connection close callback for signed data */ - if (attcCb.pSign != NULL) - { - (*attcCb.pSign->closeCback)(pClient, status); - } + /* initialize other control block variables */ + pCcb->sccb[i].control &= ~ATT_CCB_STATUS_FLOW_DISABLED; + pCcb->sccb[i].control &= ~ATT_CCB_STATUS_CNF_PENDING; - /* call pending write command callback */ - attcWriteCmdCallback(pCcb->connId, pClient, status); + /* pass to connection close callback for signed data */ + if (attcCb.pSign != NULL) + { + (*attcCb.pSign->closeCback)(pClient, status); + } + + /* call pending write command callback */ + attcWriteCmdCallback(pCcb->connId, pClient, status); + } } } @@ -609,12 +633,26 @@ static void attcConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) * \return None. */ /*************************************************************************************************/ -static void attcMsgCback(attcApiMsg_t *pMsg) +void attcMsgCback(attcApiMsg_t *pMsg) { attcCcb_t *pCcb; + ATT_TRACE_INFO2("attcMsgCback: msg: %#x slot: %#x", pMsg->hdr.event, pMsg->slot); + + /* if signed data event */ + if ((pMsg->hdr.event >= ATTC_MSG_API_SIGNED_WRITE_CMD) && (pMsg->hdr.event <= ATTC_MSG_CMAC_CMPL)) + { + /* pass to message callback for signed data */ + if (attcCb.pSign != NULL) + { + (*attcCb.pSign->msgCback)(NULL, pMsg); + } + + return; + } + /* get CCB and verify connection still in use */ - if ((pCcb = attcCcbByConnId((dmConnId_t) pMsg->hdr.param)) == NULL) + if ((pCcb = attcCcbByConnId((dmConnId_t) pMsg->hdr.param, pMsg->slot)) == NULL) { /* if message has a packet buffer */ if (pMsg->hdr.event >= ATTC_MSG_API_MTU && @@ -629,25 +667,26 @@ static void attcMsgCback(attcApiMsg_t *pMsg) } /* if an API request to send packet (non-signed) */ - if (pMsg->hdr.event <= ATTC_MSG_API_EXEC_WRITE) + if (pMsg->hdr.event <= ATTC_MSG_API_READ_MULT_VAR) { /* verify no API request already waiting on deck, in progress, or no pending write command already for this handle */ - if ((pCcb->onDeck.hdr.event != ATTC_MSG_API_NONE) || + if (((pCcb->slot == ATT_BEARER_SLOT_ID) && + (attcCb.onDeck[pCcb->connId].hdr.event != ATTC_MSG_API_NONE)) || (pCcb->outReq.hdr.event > ATTC_MSG_API_MTU) || ((pMsg->hdr.event == ATTC_MSG_API_WRITE_CMD) && - attcPendWriteCmd(pCcb, pMsg))) + attcPendWriteCmd(pCcb, pMsg->handle))) { /* free request and call callback with failure status */ - attcReqClear(pCcb, pMsg, ATT_ERR_OVERFLOW); + attcReqClear(pCcb->connId, pMsg, ATT_ERR_OVERFLOW); return; } /* if MTU request in progress or flow controlled */ - if (pCcb->outReq.hdr.event == ATTC_MSG_API_MTU || pCcb->flowDisabled) + if ((pCcb->slot == ATT_BEARER_SLOT_ID) && (pCcb->outReq.hdr.event == ATTC_MSG_API_MTU)) { /* put request "on deck" for processing later */ - pCcb->onDeck = *pMsg; + attcCb.onDeck[pCcb->connId] = *pMsg; } /* otherwise ready to send; set up request */ else @@ -655,16 +694,6 @@ static void attcMsgCback(attcApiMsg_t *pMsg) attcSetupReq(pCcb, pMsg); } } - /* else if signed data event */ - else if (pMsg->hdr.event >= ATTC_MSG_API_SIGNED_WRITE_CMD && - pMsg->hdr.event <= ATTC_MSG_CMAC_CMPL) - { - /* pass to message callback for signed data */ - if (attcCb.pSign != NULL) - { - (*attcCb.pSign->msgCback)(pCcb, pMsg); - } - } /* else if cancel request */ else if (pMsg->hdr.event == ATTC_MSG_API_CANCEL) { @@ -673,12 +702,13 @@ static void attcMsgCback(attcApiMsg_t *pMsg) pCcb->outReq.hdr.event != ATTC_MSG_API_MTU) { WsfTimerStop(&pCcb->outReqTimer); - attcReqClear(pCcb, &pCcb->outReq, ATT_ERR_CANCELLED); + attcReqClear(pCcb->connId, &pCcb->outReq, ATT_ERR_CANCELLED); } /* else free any req on deck */ - else if (pCcb->onDeck.hdr.event != ATTC_MSG_API_NONE) + else if ((pCcb->slot == ATT_BEARER_SLOT_ID) & + (attcCb.onDeck[pCcb->connId].hdr.event != ATTC_MSG_API_NONE)) { - attcReqClear(pCcb, &pCcb->onDeck, ATT_ERR_CANCELLED); + attcReqClear(pCcb->connId, &attcCb.onDeck[pCcb->connId], ATT_ERR_CANCELLED); } } /* else if timeout */ @@ -687,8 +717,8 @@ static void attcMsgCback(attcApiMsg_t *pMsg) /* free any out req */ if (pCcb->outReq.hdr.event != ATTC_MSG_API_NONE) { - attcReqClear(pCcb, &pCcb->outReq, ATT_ERR_TIMEOUT); - pCcb->pMainCcb->control |= ATT_CCB_STATUS_TX_TIMEOUT; + attcReqClear(pCcb->connId, &pCcb->outReq, ATT_ERR_TIMEOUT); + pCcb->pMainCcb->sccb[pMsg->slot].control |= ATT_CCB_STATUS_TX_TIMEOUT; } } } @@ -702,11 +732,11 @@ static void attcMsgCback(attcApiMsg_t *pMsg) * \return Pointer to connection control block or NULL if not in use. */ /*************************************************************************************************/ -attcCcb_t *attcCcbByConnId(dmConnId_t connId) +attcCcb_t *attcCcbByConnId(dmConnId_t connId, uint8_t slot) { if (DmConnInUse(connId)) { - return &attcCb.ccb[connId - 1]; + return &attcCb.ccb[connId - 1][slot]; } else { @@ -724,13 +754,13 @@ attcCcb_t *attcCcbByConnId(dmConnId_t connId) * \return Pointer to connection control block or NULL if not found. */ /*************************************************************************************************/ -attcCcb_t *attcCcbByHandle(uint16_t handle) +attcCcb_t *attcCcbByHandle(uint16_t handle, uint8_t slot) { dmConnId_t connId; if ((connId = DmConnIdByHandle(handle)) != DM_CONN_ID_NONE) { - return &attcCb.ccb[connId - 1]; + return &attcCb.ccb[connId - 1][slot]; } return NULL; @@ -785,10 +815,10 @@ void attcExecCallback(dmConnId_t connId, uint8_t event, uint16_t handle, uint8_t * \return None. */ /*************************************************************************************************/ -void attcReqClear(attcCcb_t *pCcb, attcApiMsg_t *pMsg, uint8_t status) +void attcReqClear(dmConnId_t connId, attcApiMsg_t *pMsg, uint8_t status) { attcFreePkt(pMsg); - attcExecCallback(pCcb->pMainCcb->connId, pMsg->hdr.event, pMsg->handle, status); + attcExecCallback(connId, pMsg->hdr.event, pMsg->handle, status); pMsg->hdr.event = ATTC_MSG_API_NONE; } @@ -815,7 +845,7 @@ void AttcSetAutoConfirm(bool_t enable) /*************************************************************************************************/ void AttcInit(void) { - uint8_t i; + uint8_t i, j; attcCcb_t *pCcb; /* Initialize control block */ @@ -823,14 +853,22 @@ void AttcInit(void) attcCb.autoCnf = TRUE; /* Initialize control block CCBs */ - for (i = 0, pCcb = attcCb.ccb; i < DM_CONN_MAX; i++, pCcb++) + for (i = 0; i < DM_CONN_MAX; i++) { - /* set pointer to main CCB */ - pCcb->pMainCcb = &attCb.ccb[i]; + for (j = 0; j < ATT_BEARER_MAX; j++) + { + pCcb = &attcCb.ccb[i][j]; - /* initialize timer */ - pCcb->outReqTimer.handlerId = attCb.handlerId; - pCcb->outReqTimer.msg.param = i + 1; /* param stores the conn id */ + /* set pointer to main CCB */ + pCcb->pMainCcb = &attCb.ccb[i]; + + /* initialize timer */ + pCcb->outReqTimer.handlerId = attCb.handlerId; + pCcb->outReqTimer.msg.param = i + 1; /* param stores the conn id */ + + pCcb->slot = j; + pCcb->connId = i + 1; + } } /* set up callback interface */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.h index 516ad325ca5..abfcbb24652 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATTC_MAIN_H @@ -49,6 +51,7 @@ extern "C" { #define ATT_SIGNED_WRITE_CMD_BUF_LEN (ATT_SIGNED_WRITE_CMD_LEN + L2C_PAYLOAD_START) #define ATT_PREP_WRITE_REQ_BUF_LEN (ATT_PREP_WRITE_REQ_LEN + L2C_PAYLOAD_START) #define ATT_EXEC_WRITE_REQ_BUF_LEN (ATT_EXEC_WRITE_REQ_LEN + L2C_PAYLOAD_START) +#define ATT_READ_MULT_VAR_REQ_BUF_LEN (ATT_READ_MULT_VAR_REQ_LEN + L2C_PAYLOAD_START) /* values for 'continuing' flag */ #define ATTC_CONTINUING TRUE @@ -75,6 +78,7 @@ enum ATTC_MSG_API_WRITE_CMD = ATT_METHOD_WRITE_CMD, ATTC_MSG_API_PREP_WRITE = ATT_METHOD_PREPARE_WRITE, ATTC_MSG_API_EXEC_WRITE = ATT_METHOD_EXECUTE_WRITE, + ATTC_MSG_API_READ_MULT_VAR = ATT_METHOD_READ_MULT_VAR, ATTC_MSG_API_SIGNED_WRITE_CMD, ATTC_MSG_CMAC_CMPL, ATTC_MSG_API_CANCEL, @@ -117,7 +121,7 @@ typedef union uint16_t len; attcPktParamOffset_t o; attcPktParamHandles_t h; - attcPktParamPrepWrite_t w; + attcPktParamPrepWrite_t *pW; } attcPktParam_t; /* verify attcPktParam_t will work in data buffer format described above */ @@ -129,18 +133,27 @@ typedef struct wsfMsgHdr_t hdr; attcPktParam_t *pPkt; uint16_t handle; + uint8_t slot; } attcApiMsg_t; +/* union of API parameter types */ +typedef union +{ + uint16_t len; + attcPktParamOffset_t o; + attcPktParamHandles_t h; + attcPktParamPrepWrite_t w; +} attcOutPktParam_t; + /* ATTC connection control block */ typedef struct { attCcb_t *pMainCcb; /* Pointer to ATT main CCB */ - attcApiMsg_t onDeck; /* API message "on deck" waiting to be sent */ attcApiMsg_t outReq; /* Outstanding request waiting for response */ - attcPktParam_t outReqParams; /* Parameters associated with outstanding request */ + attcOutPktParam_t outReqParams; /* Parameters associated with outstanding request */ wsfTimer_t outReqTimer; /* Outstanding request timer */ - bool_t flowDisabled; /* Data flow disabled */ - bool_t cnfPending; /* Handle value confirm packet waiting to be sent */ + uint8_t slot; /* ATT/EATT slot ID */ + dmConnId_t connId; /* DM connection ID */ uint16_t pendWriteCmdHandle[ATT_NUM_SIMUL_WRITE_CMD]; /* Callback to app pending for this write cmd handle */ } attcCcb_t; @@ -158,7 +171,8 @@ typedef struct /* Main control block of the ATTC subsystem */ typedef struct { - attcCcb_t ccb[DM_CONN_MAX]; + attcCcb_t ccb[DM_CONN_MAX][ATT_BEARER_MAX]; + attcApiMsg_t onDeck[DM_CONN_MAX]; /* API message "on deck" waiting to be sent */ attcSignFcnIf_t const *pSign; bool_t autoCnf; } attcCb_t; @@ -177,15 +191,19 @@ extern attcCb_t attcCb; Function Declarations **************************************************************************************************/ -attcCcb_t *attcCcbByConnId(dmConnId_t connId); -attcCcb_t *attcCcbByHandle(uint16_t handle); +attcCcb_t *attcCcbByConnId(dmConnId_t connId, uint8_t slot); +attcCcb_t *attcCcbByHandle(uint16_t handle, uint8_t slot); +attcPktParam_t *attcPrepWriteAllocMsg(uint16_t bufLen); void attcFreePkt(attcApiMsg_t *pMsg); void attcExecCallback(dmConnId_t connId, uint8_t event, uint16_t handle, uint8_t status); -void attcReqClear(attcCcb_t *pCcb, attcApiMsg_t *pMsg, uint8_t status); +void attcReqClear(dmConnId_t connId, attcApiMsg_t *pMsg, uint8_t status); +bool_t attcPendWriteCmd(attcCcb_t *pCcb, uint16_t handle); void attcSetupReq(attcCcb_t *pCcb, attcApiMsg_t *pMsg); void attcSendReq(attcCcb_t *pCcb); void attcSendMsg(dmConnId_t connId, uint16_t handle, uint8_t msgId, attcPktParam_t *pPkt, bool_t continuing); +void attcMsgCback(attcApiMsg_t *pMsg); +void attcWriteCmdCallback(dmConnId_t connId, attcCcb_t *pCcb, uint8_t status); void attcProcRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket); void attcProcInd(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket); @@ -198,6 +216,8 @@ void attcProcReadRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t * void attcProcReadLongRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *pEvt); void attcProcWriteRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *pEvt); void attcProcPrepWriteRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *pEvt); +void attcProcReadMultVarRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *pEvt); +void attcProcMultiVarNtf(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket); #ifdef __cplusplus }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_proc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_proc.c index a3b303b577a..edb846b4139 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_proc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_proc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client mandatory PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client mandatory PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -51,7 +53,11 @@ static const attcProcRsp_t attcProcRspTbl[] = attcProcWriteRsp, /* ATT_METHOD_WRITE */ NULL, /* ATT_METHOD_WRITE_CMD */ attcProcPrepWriteRsp, /* ATT_METHOD_PREPARE_WRITE */ - attcProcWriteRsp /* ATT_METHOD_EXECUTE_WRITE */ + attcProcWriteRsp, /* ATT_METHOD_EXECUTE_WRITE */ + NULL, /* unused */ + NULL, /* unused */ + NULL, /* unused */ + attcProcReadMultVarRsp /* ATT_METHOD_READ_MULT_VAR */ }; /*************************************************************************************************/ @@ -127,7 +133,7 @@ void attcProcMtuRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *p } /* set mtu for the connection */ - attSetMtu(pCcb->pMainCcb, mtu, WSF_MIN(pAttCfg->mtu, (HciGetMaxRxAclLen() - L2C_HDR_LEN))); + attSetMtu(pCcb->pMainCcb, pCcb->slot, mtu, WSF_MIN(pAttCfg->mtu, (HciGetMaxRxAclLen() - L2C_HDR_LEN))); } /*************************************************************************************************/ @@ -171,12 +177,12 @@ void attcProcFindOrReadRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attE else if (pCcb->outReq.hdr.event == ATTC_MSG_API_READ_BY_TYPE) { /* length in read by type response is handle plus parameter length */ - paramLen = *p++ - sizeof(uint16_t); + paramLen = *p++ - 2; } else { /* length in read by group type response is two handles plus parameter length */ - paramLen = *p++ - (2 * sizeof(uint16_t)); + paramLen = *p++ - (2 * 2); } /* get and verify all handles */ @@ -283,6 +289,59 @@ void attcProcWriteRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t pEvt->valueLen = 0; } +/*************************************************************************************************/ +/*! + * \brief Process received read multiple variable length response packet. + * + * \param pCcb Connection control block. + * \param len The length of the L2CAP payload data in pPacket. + * \param pPacket A buffer containing the packet. + * \param pEvt Pointer to callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +void attcProcReadMultVarRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt_t *pEvt) +{ + /* nothing to process */ +} + +/*************************************************************************************************/ +/*! + * \brief Process received multiple variable len notification packet. + * + * \param pCcb Connection control block. + * \param len The length of the L2CAP payload data in pPacket. + * \param pPacket A buffer containing the packet. + * + * \return None. + */ +/*************************************************************************************************/ +void attcProcMultiVarNtf(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +{ + attEvt_t evt; + uint8_t *p; + + p = pPacket + L2C_PAYLOAD_START; + + /* parse packet and set callback event struct */ + evt.hdr.event = ATT_OPCODE_2_METHOD(*p++); + evt.pValue = p; + evt.valueLen = len - ATT_HDR_LEN; + evt.hdr.param = pCcb->pMainCcb->connId; + evt.hdr.status = ATT_SUCCESS; + evt.continuing = FALSE; + + /* verify handle and call callback */ + if (attCb.cback) + { + (*attCb.cback)(&evt); + } + + /* mark confirm as pending; will be sent when flow enabled or application sends it. */ + pCcb->pMainCcb->sccb[pCcb->slot].control |= ATT_CCB_STATUS_CNF_PENDING; +} + /*************************************************************************************************/ /*! * \brief Process received response packet. @@ -341,7 +400,7 @@ void attcProcRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) } /* if no flow control */ - if (!pCcb->flowDisabled) + if (!(pCcb->pMainCcb->sccb[pCcb->slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) { /* if out req ready */ if (pCcb->outReq.pPkt != NULL) @@ -350,13 +409,14 @@ void attcProcRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) attcSendReq(pCcb); } /* else if api is on deck */ - else if (pCcb->onDeck.hdr.event != ATTC_MSG_API_NONE) + else if ((pCcb->slot == ATT_BEARER_SLOT_ID) && + (attcCb.onDeck[pCcb->connId].hdr.event != ATTC_MSG_API_NONE)) { /* set up and send request */ - attcSetupReq(pCcb, &pCcb->onDeck); + attcSetupReq(pCcb, &attcCb.onDeck[pCcb->connId]); /* clear on deck */ - pCcb->onDeck.hdr.event = ATTC_MSG_API_NONE; + attcCb.onDeck[pCcb->connId].hdr.event = ATTC_MSG_API_NONE; } } } @@ -384,7 +444,7 @@ void attcProcInd(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) evt.hdr.event = ATT_OPCODE_2_METHOD(*p++); BSTREAM_TO_UINT16(evt.handle, p); evt.pValue = p; - evt.valueLen = len - ATT_HDR_LEN - sizeof(uint16_t); + evt.valueLen = len - ATT_HDR_LEN - 2; evt.hdr.param = pCcb->pMainCcb->connId; evt.hdr.status = ATT_SUCCESS; evt.continuing = FALSE; @@ -398,7 +458,7 @@ void attcProcInd(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if indication send confirm */ if (attcCb.autoCnf && (evt.hdr.event == ATT_METHOD_VALUE_IND)) { - if (!pCcb->flowDisabled) + if (!(pCcb->pMainCcb->sccb[pCcb->slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) { if ((pPkt = attMsgAlloc(ATT_VALUE_CNF_LEN + L2C_PAYLOAD_START)) != NULL) { @@ -411,7 +471,7 @@ void attcProcInd(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket) } /* mark confirm as pending; will be sent when flow enabled or application sends it. */ - pCcb->cnfPending = TRUE; + pCcb->pMainCcb->sccb[pCcb->slot].control |= ATT_CCB_STATUS_CNF_PENDING; } /*************************************************************************************************/ @@ -436,11 +496,11 @@ void attcSendMsg(dmConnId_t connId, uint16_t handle, uint8_t msgId, attcPktParam WsfTaskLock(); /* get CCB and verify connection still in use */ - if ((pCcb = attcCcbByConnId(connId)) != NULL) + if ((pCcb = attcCcbByConnId(connId, ATT_BEARER_SLOT_ID)) != NULL) { /* get MTU size */ - mtu = pCcb->pMainCcb->mtu; - transTimedOut = !!(pCcb->pMainCcb->control & ATT_CCB_STATUS_TX_TIMEOUT); + mtu = pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].mtu; + transTimedOut = !!(pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_TX_TIMEOUT); } /* else connection not in use */ else @@ -475,7 +535,7 @@ void attcSendMsg(dmConnId_t connId, uint16_t handle, uint8_t msgId, attcPktParam if (!continuing) { /* single prepare write request */ - dataLen = ATT_PREP_WRITE_REQ_LEN + pPkt->w.len; + dataLen = ATT_PREP_WRITE_REQ_LEN + pPkt->pW->len; } /* else will be sent as multiple prepare write requests */ } @@ -495,6 +555,7 @@ void attcSendMsg(dmConnId_t connId, uint16_t handle, uint8_t msgId, attcPktParam pMsg->hdr.event = msgId; pMsg->pPkt = pPkt; pMsg->handle = handle; + pMsg->slot = ATT_BEARER_SLOT_ID; /* send message */ WsfMsgSend(attCb.handlerId, pMsg); @@ -638,12 +699,17 @@ void AttcCancelReq(dmConnId_t connId) /*************************************************************************************************/ /*! - * \brief For internal use only. + * \brief Initiate an attribute protocol Exchange MTU Request. * * \param connId DM connection ID. * \param mtu Attribute protocol MTU. * * \return None. + * + * \note The Exchange MTU Request will be initiated automatically on a master connection. + * + * \note This API can be used by the application to initiate an Exchange MTU Request on slave + * connections. */ /*************************************************************************************************/ void AttcMtuReq(dmConnId_t connId, uint16_t mtu) @@ -681,14 +747,15 @@ void AttcIndConfirm(dmConnId_t connId) attcCcb_t *pCcb; uint8_t *pPkt; - pCcb = attcCcbByHandle(connId - 1); + pCcb = attcCcbByHandle(connId - 1, ATT_BEARER_SLOT_ID); /* If confirmation is pending */ - if (pCcb && pCcb->cnfPending && !pCcb->flowDisabled) + if (pCcb && (pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_CNF_PENDING) && + !(pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_FLOW_DISABLED)) { if ((pPkt = attMsgAlloc(ATT_VALUE_CNF_LEN + L2C_PAYLOAD_START)) != NULL) { - pCcb->cnfPending = FALSE; + pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control &= ~ATT_CCB_STATUS_CNF_PENDING; *(pPkt + L2C_PAYLOAD_START) = ATT_PDU_VALUE_CNF; L2cDataReq(L2C_CID_ATT, pCcb->pMainCcb->handle, ATT_VALUE_CNF_LEN, pPkt); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_read.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_read.c index 20ad89797d2..bd2afa58c92 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_read.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_read.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client optional read PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client optional read PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -135,7 +137,7 @@ void attcProcReadLongRsp(attcCcb_t *pCcb, uint16_t len, uint8_t *pPacket, attEvt if (pCcb->outReq.hdr.status == ATTC_CONTINUING) { /* length of response is less than mtu */ - if (len < pCcb->pMainCcb->mtu) + if (len < pCcb->pMainCcb->sccb[pCcb->slot].mtu) { /* we're done */ pCcb->outReq.hdr.status = ATTC_NOT_CONTINUING; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_sign.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_sign.c index c8f5be71d9e..0595be9f0ae 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_sign.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_sign.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client optional signed PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client optional signed PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -32,6 +34,7 @@ #include "att_main.h" #include "attc_main.h" #include "att_sign.h" +#include "wsf_trace.h" /************************************************************************************************** Data Types @@ -133,13 +136,13 @@ static void attcSignCloseCback(attcCcb_t *pCcb, uint8_t status) attcSignCb_t *pCb; /* if connection closed while processing in progress */ - if ((pCb = attcSignCbByConnId(pCcb->pMainCcb->connId)) != NULL) + if ((pCb = attcSignCbByConnId(pCcb->connId)) != NULL) { /* message free buffer */ if (pCb->msg.hdr.event != ATTC_MSG_API_NONE) { - attcReqClear(pCcb, &pCb->msg, status); + attcReqClear(pCcb->connId, &pCb->msg, status); } attcSignCbFree(pCcb->pMainCcb->connId); @@ -150,7 +153,7 @@ static void attcSignCloseCback(attcCcb_t *pCcb, uint8_t status) /*! * \brief Message handler callback for ATTC signed PDU processing. * - * \param pCcb ATT control block. + * \param pCcb ATT control block. * \param pMsg ATTC message. * * \return None. @@ -159,6 +162,13 @@ static void attcSignCloseCback(attcCcb_t *pCcb, uint8_t status) static void attcSignMsgCback(attcCcb_t *pCcb, attcSignMsg_t *pMsg) { attcSignCb_t *pCb; + + /* cannot assume pCcb parameter is valid for signed writes */ + if ((pCcb = attcCcbByConnId((dmConnId_t) pMsg->hdr.param, ATT_BEARER_SLOT_ID)) == NULL) + { + /* connection not in use */ + return; + } if (pMsg->hdr.event == ATTC_MSG_API_SIGNED_WRITE_CMD) { @@ -168,12 +178,12 @@ static void attcSignMsgCback(attcCcb_t *pCcb, attcSignMsg_t *pMsg) /* verify no API request already waiting on deck or in progress, * and no signed write already in progress */ - if ((pCcb->onDeck.hdr.event != ATTC_MSG_API_NONE) || + if ((attcCb.onDeck[pCcb->connId].hdr.event != ATTC_MSG_API_NONE) || (pCcb->outReq.hdr.event > ATTC_MSG_API_MTU) || (attcSignCbByConnId((dmConnId_t) pMsg->hdr.param) != NULL)) { /* free request and call callback with failure status */ - attcReqClear(pCcb, &pMsg->api, ATT_ERR_OVERFLOW); + attcReqClear(pCcb->connId, &pMsg->api, ATT_ERR_OVERFLOW); return; } @@ -207,7 +217,7 @@ static void attcSignMsgCback(attcCcb_t *pCcb, attcSignMsg_t *pMsg) else { /* allocation failure */ - attcReqClear(pCcb, &pMsg->api, ATT_ERR_UNDEFINED); + attcReqClear(pCcb->connId, &pMsg->api, ATT_ERR_UNDEFINED); return; } } @@ -224,10 +234,11 @@ static void attcSignMsgCback(attcCcb_t *pCcb, attcSignMsg_t *pMsg) pCmacMsg->pCiphertext, ATT_CMAC_RESULT_LEN); /* if MTU request in progress or flow controlled */ - if (pCcb->outReq.hdr.event == ATTC_MSG_API_MTU || pCcb->flowDisabled) + if (pCcb->outReq.hdr.event == ATTC_MSG_API_MTU || + pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_FLOW_DISABLED) { /* put request "on deck" for processing later */ - pCcb->onDeck = pCb->msg; + attcCb.onDeck[pCcb->connId] = pCb->msg; } /* otherwise ready to send */ else @@ -259,7 +270,7 @@ void AttcSignedWriteCmd(dmConnId_t connId, uint16_t handle, uint32_t signCounter { attcPktParam_t *pPkt; uint8_t *p; - + /* if connection already encrypted with security mode 1 level 2 or higher */ if (DmConnSecLevel(connId) > DM_SEC_LEVEL_NONE) { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_write.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_write.c index 601c5f38785..7602baa5ffa 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_write.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/attc_write.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client optional write PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client optional write PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -28,6 +30,35 @@ #include "att_main.h" #include "attc_main.h" +/*************************************************************************************************/ +/*! + * \brief Allocate an ATT Prepare Write Request message buffer. + * + * \param bufLen Lenght of buffer to be allocated. + * + * \return Pointer to data message buffer or NULL if allocation failed. + */ +/*************************************************************************************************/ +attcPktParam_t *attcPrepWriteAllocMsg(uint16_t bufLen) +{ + attcPktParam_t *pPkt; + + /* if buffer length is not memory address aligned */ + if (bufLen % sizeof(void *) != 0) + { + bufLen += sizeof(void *) - (bufLen % sizeof(void *)); + } + + /* allocate packet and parameter buffer */ + if ((pPkt = attMsgAlloc(bufLen + sizeof(attcPktParamPrepWrite_t))) != NULL) + { + /* set parameter */ + pPkt->pW = (attcPktParamPrepWrite_t *) ((uint8_t *) pPkt + bufLen); + } + + return pPkt; +} + /*************************************************************************************************/ /*! * \brief Process received Prepare Write response packet. @@ -124,11 +155,11 @@ void AttcPrepareWriteReq(dmConnId_t connId, uint16_t handle, uint16_t offset, ui } /* allocate packet and parameter buffer */ - if ((pPkt = attMsgAlloc(bufLen)) != NULL) + if ((pPkt = attcPrepWriteAllocMsg(bufLen)) != NULL) { /* set parameters */ - pPkt->w.len = valueLen; - pPkt->w.offset = offset; + pPkt->pW->len = valueLen; + pPkt->pW->offset = offset; /* build partial packet */ p = (uint8_t *) pPkt + L2C_PAYLOAD_START; @@ -141,12 +172,12 @@ void AttcPrepareWriteReq(dmConnId_t connId, uint16_t handle, uint16_t offset, ui /* set value pointer and copy data to packet, if not valueByRef */ if (continuing && valueByRef) { - pPkt->w.pValue = pValue; + pPkt->pW->pValue = pValue; } else { memcpy(p, pValue, valueLen); - pPkt->w.pValue = p; + pPkt->pW->pValue = p; } /* send message */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ccc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ccc.c index 5ae97ba5409..3f230970d8b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ccc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ccc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client characteristic configuration module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client characteristic configuration module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_csf.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_csf.c index ca7a1847fb7..ed4f051194b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_csf.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_csf.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT client supported features module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT client supported features module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -253,7 +255,7 @@ uint8_t attsCsfActClientState(uint16_t handle, uint8_t opcode, uint8_t *pPacket) * application) will have updated all persistent records prior to calling this function. */ /*************************************************************************************************/ -void AttsCsfSetClientsChangeAwarenessState(dmConnId_t connId, uint8_t state) +void AttsCsfSetClientChangeAwareState(dmConnId_t connId, uint8_t state) { if (connId == DM_CONN_ID_NONE) { @@ -346,6 +348,7 @@ void AttsCsfInit(void) uint8_t AttsCsfWriteFeatures(dmConnId_t connId, uint16_t offset, uint16_t valueLen, uint8_t *pValue) { attsCsfRec_t *pCsfRec = &attsCsfCb.attsCsfTable[connId - 1]; + uint8_t newCsf; /* future parameter in case the client supported features characteristic becomes a multi-octet * structure. @@ -356,14 +359,16 @@ uint8_t AttsCsfWriteFeatures(dmConnId_t connId, uint16_t offset, uint16_t valueL { return ATT_ERR_LENGTH; } + + newCsf = *pValue & ATTS_CSF_ALL_FEATURES; - /* A client can not clear any bits it has set. */ - if ((pCsfRec->csf & *pValue) < pCsfRec->csf) + /* A client cannot clear any bits it has set. */ + if ((pCsfRec->csf > 0) && (newCsf == 0)) { return ATT_ERR_VALUE_NOT_ALLOWED; } - pCsfRec->csf = *pValue & ATTS_CSF_OCT0_FEATURES; + pCsfRec->csf |= newCsf; ATT_TRACE_INFO2("connId %d updated csf to 0x%02x", connId, pCsfRec->csf); @@ -401,10 +406,10 @@ void AttsCsfGetFeatures(dmConnId_t connId, uint8_t *pCsfOut, uint8_t pCsfOutLen) * * \param connId DM connection ID. * - * \return Client's change-aware state. + * \return Client's change-aware state. See ::attClientAwareStates. */ /*************************************************************************************************/ -uint8_t AttsCsfGetChangeAwareState(dmConnId_t connId) +uint8_t AttsCsfGetClientChangeAwareState(dmConnId_t connId) { return attsCsfCb.attsCsfTable[connId - 1].changeAwareState; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_dyn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_dyn.c index e967dd74f34..a125a644317 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_dyn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_dyn.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Dynamic ATT services and attributes. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2017-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Dynamic ATT services and attributes. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_eatt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_eatt.c new file mode 100644 index 00000000000..f1ca4879c8c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_eatt.c @@ -0,0 +1,526 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Enhanced ATT (EATT) server. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_timer.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_os.h" +#include "util/bstream.h" +#include "l2c_api.h" +#include "l2c_main.h" +#include "dm_api.h" +#include "att_api.h" +#include "att_main.h" +#include "atts_main.h" +#include "eatt_api.h" +#include "att_eatt.h" +#include "svc_core.h" + +/************************************************************************************************** + Function Prototypes +**************************************************************************************************/ + +static void eattsL2cCocDataInd(l2cCocEvt_t *pEvt); +static void eattsL2cCocDataCnf(l2cCocEvt_t *pEvt); +static void eattsConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/* Interface to ATT */ +static const eattFcnIf_t attsFcnIf = +{ + eattsL2cCocDataInd, + eattsL2cCocDataCnf, + (attMsgHandler_t) attsMsgCback, + eattsConnCback +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +extern attsProcFcn_t attsProcFcnTbl[]; +extern const uint8_t attsMinPduLen[]; + +/*************************************************************************************************/ +/*! + * \brief Get a channel for transmission of an EATT server message. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param dataLen Length of value data. + * + * \return Slot ID + */ +/*************************************************************************************************/ +static uint8_t eattsGetFreeSlot(dmConnId_t connId, uint8_t priority, uint16_t dataLen) +{ + eattConnCb_t *pCcb = eattGetConnCb(connId); + attCcb_t *pAttCcb = attCcbByConnId(connId); + + if (pCcb && pAttCcb) + { + uint8_t i; + + for (i = 0; i < EATT_CONN_CHAN_MAX; i++) + { + eattChanCb_t *pChanCb = &pCcb->pChanCb[i]; + + if (pChanCb->inUse && (pChanCb->priority >= priority) && (pChanCb->localMtu >= dataLen)) + { + if (!(pAttCcb->sccb[i].control & ATT_CCB_STATUS_RSP_PENDING)) + { + EATT_TRACE_INFO1("eattsGetFreeSlot: allocating slot: %#x", i + 1); + return i + 1; + } + } + } + } + + return ATT_BEARER_SLOT_ID; +} + +/*************************************************************************************************/ +/*! + * \brief L2CAP CoC data indication callback function. + * + * \param pEvt Pointer to event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattsL2cCocDataInd(l2cCocEvt_t *pEvt) +{ + l2cCocDataInd_t *pDataInd = &pEvt->dataInd; + uint8_t opcode; + uint8_t method; + uint8_t err; + uint16_t attHandle; + attsProcFcn_t procFcn; + dmConnId_t connId = (dmConnId_t) pDataInd->hdr.param; + uint8_t slot = eattGetSlotId(connId, pDataInd->cid); + attCcb_t *pAttCcb = attCcbByConnId(connId); + attsCcb_t *pAttsCcb = attsCcbByConnId(connId, slot); + uint16_t len = pEvt->dataInd.dataLen; + + if (slot != ATT_BEARER_SLOT_INVALID) + { + /* parse opcode */ + opcode = *(pDataInd->pData); + + /* get method */ + if ((opcode <= ATT_PDU_WRITE_REQ) || + ((opcode >= ATT_PDU_PREP_WRITE_REQ) && (opcode <= ATT_PDU_VALUE_CNF))) + { + method = ATT_OPCODE_2_METHOD(opcode); + } + else if (opcode == ATT_PDU_WRITE_CMD) + { + method = ATT_METHOD_WRITE_CMD; + } + else if (opcode == ATT_PDU_READ_MULT_VAR_REQ) + { + method = ATT_METHOD_READ_MULT_VAR; + } + else if (opcode == ATT_PDU_SIGNED_WRITE_CMD) + { + method = ATT_METHOD_SIGNED_WRITE_CMD; + } + else + { + method = ATT_METHOD_ERR; + } + + /* ignore packet if write response is pending. */ + if (pAttCcb->sccb[slot].control & ATT_CCB_STATUS_RSP_PENDING) + { + if (method != ATT_METHOD_VALUE_CNF) + { + return; + } + } + + /* check client's status to see if server is allowed to process this PDU. */ + err = attsCsfActClientState(connId - 1, opcode, pEvt->dataInd.pData - L2C_PAYLOAD_START); + if (err) + { + BYTES_TO_UINT16(attHandle, pEvt->dataInd.pData + ATT_HDR_LEN); + } + else + { + attHandle = ATT_HANDLE_NONE; + } + +#if defined(ATTS_ERROR_TEST) && (ATTS_ERROR_TEST == TRUE) + if (attCb.errTest != ATT_SUCCESS) + { + attsErrRsp(pAttCcb, ATT_BEARER_SLOT_ID, opcode, attHandle, attCb.errTest); + return; + } +#endif + + /* if no error process request */ + if (!err) + { + /* look up processing function */ + procFcn = attsProcFcnTbl[method]; + + /* if method is supported */ + if (procFcn != NULL) + { + /* verify length */ + if (len >= attsMinPduLen[method]) + { + /* execute processing function */ + (*procFcn)(pAttsCcb, len, pEvt->dataInd.pData - L2C_PAYLOAD_START); + err = 0; + } + else + { + /* invalid PDU length */ + err = ATT_ERR_INVALID_PDU; + } + } + else + { + /* PDU not supported */ + err = ATT_ERR_NOT_SUP; + } + } + + /* if there's an error and an error response can be sent for this opcode */ + if (err && (opcode != ATT_PDU_MTU_REQ) && (opcode != ATT_PDU_VALUE_CNF) && + ((opcode & ATT_PDU_MASK_COMMAND) == 0)) + { + attsErrRsp(pAttCcb, slot, opcode, attHandle, err); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief L2CAP CoC data confirm callback function. + * + * \param pEvt Pointer to event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattsL2cCocDataCnf(l2cCocEvt_t *pEvt) +{ + dmConnId_t connId = (dmConnId_t) pEvt->dataCnf.hdr.param; + uint8_t slot = eattGetSlotId(connId, pEvt->dataCnf.cid); + attsCcb_t *pCcb; + + /* note this function is currently only called when flow is enabled */ + + if (slot != ATT_BEARER_SLOT_INVALID) + { + /* get CCB */ + if ((pCcb = attsCcbByConnId(connId, slot)) != NULL) + { + /* call pending indication and notification callback */ + attsIndNtfCallback(connId, pCcb, ATT_SUCCESS); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Connection callback for ATTS. + * + * \param pCcb ATT control block. + * \param pDmEvt DM callback event. + * + * \return None. + */ +/*************************************************************************************************/ +static void eattsConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) +{ + (void) pCcb; + (void) pDmEvt; + + /* take no action */ +} + +/*************************************************************************************************/ +/*! + * \brief Calculate the length of a list of handle length value tupples. + * + * \param numTuples The number of tuples. + * \param pTupleList Pointer to a list of tuples. + * + * \return length of tupples. + */ +/*************************************************************************************************/ +static uint16_t eattMultiNtfLen(uint16_t numTuples, eattTuple_t *pTupleList) +{ + uint8_t i; + uint16_t len = 0; + + for (i = 0; i < numTuples; i++) + { + len += pTupleList[i].len + sizeof(uint16_t) * 2; + } + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Send multiple attribute protocol Handle Value Notification. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param numTuples The number of tuples. + * \param pTupleList Pointer to a list of tuples. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsMultiValueNtf(dmConnId_t connId, uint8_t priority, uint16_t numTuples, eattTuple_t *pTupleList) +{ + uint16_t valueLen = eattMultiNtfLen(numTuples, pTupleList); + uint8_t slot; + bool_t msgSent = FALSE; + + WsfTaskLock(); + + slot = eattsGetFreeSlot(connId, priority, valueLen + ATT_MULT_VALUE_NTF_BUF_LEN); + + WsfTaskUnlock(); + + if (slot) + { + /* Only send notifications and indications if client is aware of any database changes. */ + if (attsCsfIsClientChangeAware(connId, 0)) + { + attsApiMsg_t *pMsg; + uint8_t *p; + uint8_t i; + + /* allocate message buffer */ + if ((pMsg = WsfMsgAlloc(sizeof(attsApiMsg_t))) != NULL) + { + /* set parameters */ + pMsg->hdr.param = connId; + pMsg->hdr.event = ATTS_MSG_API_VALUE_IND_NTF; + pMsg->slot = slot; + pMsg->pPkt = attMsgAlloc(ATT_MULT_VALUE_NTF_BUF_LEN + valueLen); + + if (pMsg->pPkt != NULL) + { + /* set data length and handle (ind and ntf have same header length) */ + pMsg->pPkt->len = ATT_PDU_MULT_VALUE_NTF_LEN + valueLen; + + /* build packet */ + p = (uint8_t *)pMsg->pPkt + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_MULT_VALUE_NTF); + + for (i = 0; i < numTuples; i++) + { + UINT16_TO_BSTREAM(p, pTupleList[i].handle); + UINT16_TO_BSTREAM(p, pTupleList[i].len); + memcpy(p, pTupleList[i].pValue, pTupleList[i].len); + p += pTupleList[i].len; + } + + /* send message */ + WsfMsgSend(attCb.handlerId, pMsg); + msgSent = TRUE; + } + else + { + /* free message buffer if packet buffer alloc failed */ + WsfMsgFree(pMsg); + } + } + } + + if (!msgSent) + { + /* Failed to send the packet, release the slot. */ + attExecCallback(connId, ATTS_MULT_VALUE_CNF, 0, ATT_ERR_MEMORY, 0); + } + } + else + { + /* call callback with no channel available status */ + attExecCallback(connId, ATTS_MULT_VALUE_CNF, 0, ATT_ERR_NO_CHANNEL, 0); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Indication. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueInd(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue) +{ + uint8_t slot = eattsGetFreeSlot(connId, priority, valueLen); + attsHandleValueIndNtf(connId, handle, slot, valueLen, pValue, ATT_PDU_VALUE_IND, FALSE); +} + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Notification. + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueNtf(dmConnId_t connId, uint8_t priority, uint16_t handle, uint16_t valueLen, + uint8_t *pValue) +{ + uint8_t slot = eattsGetFreeSlot(connId, priority, valueLen); + attsHandleValueIndNtf(connId, handle, slot, valueLen, pValue, ATT_PDU_VALUE_NTF, FALSE); +} + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Indication without copying the attribute + * value data. + * + * Note: attribute value buffer 'pValue' must be allocated with AttMsgAlloc(). + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueIndZeroCpy(dmConnId_t connId, uint8_t priority, uint16_t handle, + uint16_t valueLen, uint8_t *pValue) +{ + uint8_t slot = eattsGetFreeSlot(connId, priority, valueLen); + attsHandleValueIndNtf(connId, handle, slot, valueLen, pValue, ATT_PDU_VALUE_IND, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief Send an attribute protocol Handle Value Notification without copying the attribute + * value data. + * + * Note: attribute value buffer 'pValue' must be allocated with AttMsgAlloc(). + * + * \param connId DM connection ID. + * \param priority Operation priority. + * \param handle Attribute handle. + * \param valueLen Length of value data. + * \param pValue Pointer to value data. + * + * \return None. + */ +/*************************************************************************************************/ +void EattsHandleValueNtfZeroCpy(dmConnId_t connId, uint8_t priority, uint16_t handle, + uint16_t valueLen, uint8_t *pValue) +{ + uint8_t slot = eattsGetFreeSlot(connId, priority, valueLen); + attsHandleValueIndNtf(connId, handle, slot, valueLen, pValue, ATT_PDU_VALUE_NTF, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief Send a response to a pending write request. For use with ATT_RSP_PENDING. + * + * \param connId Connection ID. + * \param slot EATT channel slot ID. + * \param handle Attribute handle. + * \param status Status of the write request. + * + * \return None. + * + * \note When a higher layer returns ATT_RSP_PENDING to an ATT write callback indicating the + * response status is pending, the higher layer must subsequently call this function + * with the status of the write request. + */ +/*************************************************************************************************/ +void EattsContinueWriteReq(dmConnId_t connId, uint8_t slot, uint16_t handle, uint8_t status) +{ + attCcb_t *pCcb; + uint8_t *pBuf; + uint8_t *p; + + /* get connection cb for this handle */ + if ((pCcb = attCcbByConnId(connId)) == NULL) + { + return; + } + + if (pCcb->sccb[slot].control & ATT_CCB_STATUS_RSP_PENDING) + { + /* clear response pending */ + pCcb->sccb[slot].control &= ~ATT_CCB_STATUS_RSP_PENDING; + + if (status) + { + attsErrRsp(pCcb, slot, ATT_PDU_WRITE_REQ, handle, status); + } + else + { + if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + ATT_WRITE_RSP_LEN)) != NULL) + { + /* build and send PDU */ + p = pBuf + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_RSP); + + attL2cDataReq(pCcb, slot, ATT_WRITE_RSP_LEN, pBuf); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the Enhanced ATT Server. + * + * \return None + */ + /*************************************************************************************************/ +void EattsInit() +{ + /* set up callback interface */ + attCb.pEnServer = &attsFcnIf; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ind.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ind.c index f9c357f9149..803f1fefb24 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ind.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_ind.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief ATT server indication and notification functions. + * \file + * + * \brief ATT server indication and notification functions. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -51,35 +53,6 @@ static const attFcnIf_t attsIndFcnIf = attsIndConnCback }; -/************************************************************************************************** - Global Variables -**************************************************************************************************/ - -/* Control block */ -attsIndCb_t attsIndCb; - -/*************************************************************************************************/ -/*! - * \brief Return the ATTS connection control block connection ID. - * - * \param connId Connection ID. - * - * \return Pointer to connection control block or NULL if not in use. - */ -/*************************************************************************************************/ -static attsIndCcb_t *attsIndCcbByConnId(dmConnId_t connId) -{ - if (DmConnInUse(connId)) - { - return &attsIndCb.ccb[connId - 1]; - } - else - { - ATT_TRACE_WARN1("atts ccb not in use: %d", connId); - return NULL; - } -} - /*************************************************************************************************/ /*! * \brief Check if application callback is pending for indication or a given notification, or @@ -92,7 +65,7 @@ static attsIndCcb_t *attsIndCcbByConnId(dmConnId_t connId) * FALSE, otherwise. */ /*************************************************************************************************/ -static bool_t attsPendIndNtfHandle(attsIndCcb_t *pCcb, attsPktParam_t *pPkt) +static bool_t attsPendIndNtfHandle(attsCcb_t *pCcb, attsPktParam_t *pPkt) { uint8_t opcode; uint8_t pendNtfs; @@ -142,7 +115,7 @@ static bool_t attsPendIndNtfHandle(attsIndCcb_t *pCcb, attsPktParam_t *pPkt) * \return None. */ /*************************************************************************************************/ -static void attsSetPendNtfHandle(attsIndCcb_t *pCcb, uint16_t handle) +static void attsSetPendNtfHandle(attsCcb_t *pCcb, uint16_t handle) { uint8_t i; @@ -185,7 +158,7 @@ static void attsExecCallback(dmConnId_t connId, uint16_t handle, uint8_t status) * \return None. */ /*************************************************************************************************/ -static void attsIndNtfCallback(dmConnId_t connId, attsIndCcb_t *pCcb, uint8_t status) +void attsIndNtfCallback(dmConnId_t connId, attsCcb_t *pCcb, uint8_t status) { uint8_t i; @@ -220,7 +193,7 @@ static void attsIndNtfCallback(dmConnId_t connId, attsIndCcb_t *pCcb, uint8_t st * \return None. */ /*************************************************************************************************/ -static void attsSetupMsg(attsIndCcb_t *pCcb, dmConnId_t connId, attsPktParam_t *pPkt) +static void attsSetupMsg(attsCcb_t *pCcb, dmConnId_t connId, uint8_t slot, attsPktParam_t *pPkt) { uint8_t opcode; uint16_t handle; @@ -232,19 +205,28 @@ static void attsSetupMsg(attsIndCcb_t *pCcb, dmConnId_t connId, attsPktParam_t * handle = pPkt->handle; /* send pdu */ - L2cDataReq(L2C_CID_ATT, pCcb->pMainCcb->handle, pPkt->len, (uint8_t *) pPkt); + attL2cDataReq(pCcb->pMainCcb, slot, pPkt->len, (uint8_t *) pPkt); /* if indication store handle and start timer */ if (opcode == ATT_PDU_VALUE_IND) { pCcb->outIndHandle = pCcb->pendIndHandle = handle; pCcb->outIndTimer.msg.event = ATTS_MSG_IND_TIMEOUT; + pCcb->outIndTimer.msg.param = attMsgParam(pCcb->connId, pCcb->slot); + WsfTimerStartSec(&pCcb->outIndTimer, pAttCfg->transTimeout); } /* else if a notification and flow not disabled call callback now */ - else if (!(pCcb->pMainCcb->control & ATT_CCB_STATUS_FLOW_DISABLED)) + else if (!(pCcb->pMainCcb->sccb[slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) { - attsExecCallback(connId, handle, ATT_SUCCESS); + if (opcode == ATT_PDU_MULT_VALUE_NTF) + { + attExecCallback(connId, ATTS_MULT_VALUE_CNF, handle, ATT_SUCCESS, 0); + } + else + { + attsExecCallback(connId, handle, ATT_SUCCESS); + } } /* else set pending notification callback for this handle */ else @@ -265,8 +247,9 @@ static void attsSetupMsg(attsIndCcb_t *pCcb, dmConnId_t connId, attsPktParam_t * /*************************************************************************************************/ static void attsIndConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) { - attsIndCcb_t *pIndCcb; + attsCcb_t *pAttsCcb; uint8_t status; + uint8_t i; /* if connection opened */ if (pDmEvt->hdr.event == DM_CONN_OPEN_IND) @@ -286,19 +269,22 @@ static void attsIndConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) status = pDmEvt->connClose.hdr.status + ATT_HCI_ERR_BASE; } - /* get server control block directly */ - pIndCcb = &attsIndCb.ccb[pCcb->connId - 1]; - - /* if outstanding indication */ - if (pIndCcb->outIndHandle != ATT_HANDLE_NONE) + for (i = 0; i < ATT_BEARER_MAX; i++) { - /* stop timer */ - WsfTimerStop(&pIndCcb->outIndTimer); - pIndCcb->outIndHandle = ATT_HANDLE_NONE; - } + /* get server control block directly */ + pAttsCcb = &attsCb.ccb[pCcb->connId - 1][i]; - /* call pending indication and notification callback */ - attsIndNtfCallback(pCcb->connId, pIndCcb, status); + /* if outstanding indication */ + if (pAttsCcb->outIndHandle != ATT_HANDLE_NONE) + { + /* stop timer */ + WsfTimerStop(&pAttsCcb->outIndTimer); + pAttsCcb->outIndHandle = ATT_HANDLE_NONE; + } + + /* call pending indication and notification callback */ + attsIndNtfCallback(pCcb->connId, pAttsCcb, status); + } } } @@ -313,24 +299,21 @@ static void attsIndConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) /*************************************************************************************************/ static void attsIndMsgCback(attsApiMsg_t *pMsg) { - attsIndCcb_t *pCcb; + attsCcb_t *pCcb; - /* get CCB and verify connection still in use */ - if ((pCcb = attsIndCcbByConnId((dmConnId_t) pMsg->hdr.param)) == NULL) + /* if an API message to send packet */ + if (pMsg->hdr.event == ATTS_MSG_API_VALUE_IND_NTF) { - /* if message has a packet buffer free packet buffer */ - if (pMsg->hdr.event == ATTS_MSG_API_VALUE_IND_NTF) + /* get CCB and verify connection still in use */ + if ((pCcb = attsCcbByConnId((dmConnId_t) pMsg->hdr.param, pMsg->slot)) == NULL) { + /* if message has a packet buffer free packet buffer */ WsfMsgFree(pMsg->pPkt); - } - /* ignore if connection not in use */ - return; - } + /* ignore if connection not in use */ + return; + } - /* if an API message to send packet */ - if (pMsg->hdr.event == ATTS_MSG_API_VALUE_IND_NTF) - { /* verify no API message already pending */ if (attsPendIndNtfHandle(pCcb, pMsg->pPkt)) { @@ -341,12 +324,24 @@ static void attsIndMsgCback(attsApiMsg_t *pMsg) /* otherwise ready to send; set up request */ else { - attsSetupMsg(pCcb, (dmConnId_t) pMsg->hdr.param, pMsg->pPkt); + attsSetupMsg(pCcb, (dmConnId_t) pMsg->hdr.param, pMsg->slot, pMsg->pPkt); } } /* else if indication timeout */ else if (pMsg->hdr.event == ATTS_MSG_IND_TIMEOUT) { + dmConnId_t connId; + uint8_t slot; + + attDecodeMsgParam(pMsg->hdr.param, &connId, &slot); + pMsg->hdr.param = connId; + + if ((pCcb = attsCcbByConnId(connId, slot)) == NULL) + { + /* ignore if connection not in use */ + return; + } + /* if outstanding indication */ if (pCcb->outIndHandle != ATT_HANDLE_NONE) { @@ -354,9 +349,9 @@ static void attsIndMsgCback(attsApiMsg_t *pMsg) pCcb->outIndHandle = ATT_HANDLE_NONE; /* call callback with timeout error */ - attsExecCallback((dmConnId_t) pMsg->hdr.param, pCcb->pendIndHandle, ATT_ERR_TIMEOUT); + attsExecCallback(connId, pCcb->pendIndHandle, ATT_ERR_TIMEOUT); pCcb->pendIndHandle = ATT_HANDLE_NONE; - pCcb->pMainCcb->control |= ATT_CCB_STATUS_TX_TIMEOUT; + pCcb->pMainCcb->sccb[pMsg->slot].control |= ATT_CCB_STATUS_TX_TIMEOUT; } } } @@ -372,12 +367,12 @@ static void attsIndMsgCback(attsApiMsg_t *pMsg) /*************************************************************************************************/ static void attsIndCtrlCback(wsfMsgHdr_t *pMsg) { - attsIndCcb_t *pCcb; + attsCcb_t *pCcb; /* note this function is currently only called when flow is enabled */ /* get CCB */ - if ((pCcb = attsIndCcbByConnId((dmConnId_t) pMsg->param)) != NULL) + if ((pCcb = attsCcbByConnId((dmConnId_t) pMsg->param, ATT_BEARER_SLOT_ID)) != NULL) { /* call pending indication and notification callback */ attsIndNtfCallback((dmConnId_t) pMsg->param, pCcb, ATT_SUCCESS); @@ -390,6 +385,7 @@ static void attsIndCtrlCback(wsfMsgHdr_t *pMsg) * * \param connId DM connection ID. * \param handle Attribute handle. + * \param slot EATT/ATT slot ID. * \param valueLen Length of value data. * \param pValue Pointer to value data. * \param opcode Opcode for notification or indication. @@ -398,10 +394,10 @@ static void attsIndCtrlCback(wsfMsgHdr_t *pMsg) * \return None. */ /*************************************************************************************************/ -static void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint16_t valueLen, +void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint8_t slot, uint16_t valueLen, uint8_t *pValue, uint8_t opcode, bool_t zeroCpy) { - attsIndCcb_t *pCcb; + attsCcb_t *pCcb; uint16_t mtu; bool_t transTimedOut; bool_t pktSent = FALSE; @@ -409,11 +405,11 @@ static void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint16_t v WsfTaskLock(); /* get CCB and verify connection still in use */ - if ((pCcb = attsIndCcbByConnId(connId)) != NULL) + if ((pCcb = attsCcbByConnId(connId, slot)) != NULL) { /* get MTU size */ - mtu = pCcb->pMainCcb->mtu; - transTimedOut = !!(pCcb->pMainCcb->control & ATT_CCB_STATUS_TX_TIMEOUT); + mtu = pCcb->pMainCcb->sccb[slot].mtu; + transTimedOut = !!(pCcb->pMainCcb->sccb[slot].control & ATT_CCB_STATUS_TX_TIMEOUT); } /* else connection not in use */ else @@ -446,6 +442,7 @@ static void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint16_t v /* set parameters */ pMsg->hdr.param = connId; pMsg->hdr.event = ATTS_MSG_API_VALUE_IND_NTF; + pMsg->slot = slot; if (zeroCpy) { @@ -520,30 +517,34 @@ static void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint16_t v * \return None. */ /*************************************************************************************************/ -void attsProcValueCnf(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcValueCnf(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { - attsIndCcb_t *pIndCcb; - - /* get server indication CCB */ - if ((pIndCcb = attsIndCcbByConnId(pCcb->connId)) == NULL) - { - return; - } - /* if an outstanding indication */ - if (pIndCcb->outIndHandle != ATT_HANDLE_NONE) + if (pCcb->outIndHandle != ATT_HANDLE_NONE) { - /* clear outstanding indication */ - pIndCcb->outIndHandle = ATT_HANDLE_NONE; + attsAttr_t *pAttr; + attsGroup_t *pGroup; /* stop indication timer */ - WsfTimerStop(&pIndCcb->outIndTimer); + WsfTimerStop(&pCcb->outIndTimer); + + /* if client is unaware of a database update and this confirmation is for a service change + * indication, transition client to the change-aware state */ + if (((pAttr = attsFindByHandle(pCcb->outIndHandle, &pGroup)) != NULL) && + (memcmp(pAttr->pUuid, attScChUuid, ATT_16_UUID_LEN) == 0) && + (AttsCsfGetClientChangeAwareState(pCcb->connId) != ATTS_CLIENT_CHANGE_AWARE)) + { + AttsCsfSetClientChangeAwareState(pCcb->connId, ATTS_CLIENT_CHANGE_AWARE); + } + + /* clear outstanding indication */ + pCcb->outIndHandle = ATT_HANDLE_NONE; /* call callback if flow control permits */ - if (!(pCcb->control & ATT_CCB_STATUS_FLOW_DISABLED)) + if (!(pCcb->pMainCcb->sccb[pCcb->slot].control & ATT_CCB_STATUS_FLOW_DISABLED)) { - attsExecCallback(pCcb->connId, pIndCcb->pendIndHandle, ATT_SUCCESS); - pIndCcb->pendIndHandle = ATT_HANDLE_NONE; + attsExecCallback(pCcb->connId, pCcb->pendIndHandle, ATT_SUCCESS); + pCcb->pendIndHandle = ATT_HANDLE_NONE; } } } @@ -557,18 +558,23 @@ void attsProcValueCnf(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /*************************************************************************************************/ void AttsIndInit(void) { - uint8_t i; - attsIndCcb_t *pCcb; + uint8_t i, j; + attsCcb_t *pCcb; + + /* Number of slots times channels cannot excede 0xFF */ + WSF_ASSERT(((ATT_BEARER_MAX) * DM_CONN_MAX) > sizeof(uint8_t)) /* Initialize control block CCBs */ - for (i = 0, pCcb = attsIndCb.ccb; i < DM_CONN_MAX; i++, pCcb++) + for (i = 0; i < DM_CONN_MAX; i++) { - /* set pointer to main CCB */ - pCcb->pMainCcb = &attCb.ccb[i]; + for (j = 0; j < ATT_BEARER_MAX; j++) + { + pCcb = &attsCb.ccb[i][j]; - /* initialize timer */ - pCcb->outIndTimer.handlerId = attCb.handlerId; - pCcb->outIndTimer.msg.param = i + 1; /* param stores the conn id */ + /* initialize timer */ + pCcb->outIndTimer.handlerId = attCb.handlerId; + pCcb->outIndTimer.msg.param = i + 1; /* param stores the conn id */ + } } /* set up callback interface */ @@ -589,7 +595,7 @@ void AttsIndInit(void) /*************************************************************************************************/ void AttsHandleValueInd(dmConnId_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue) { - attsHandleValueIndNtf(connId, handle, valueLen, pValue, ATT_PDU_VALUE_IND, FALSE); + attsHandleValueIndNtf(connId, handle, ATT_BEARER_SLOT_ID, valueLen, pValue, ATT_PDU_VALUE_IND, FALSE); } /*************************************************************************************************/ @@ -606,7 +612,7 @@ void AttsHandleValueInd(dmConnId_t connId, uint16_t handle, uint16_t valueLen, u /*************************************************************************************************/ void AttsHandleValueNtf(dmConnId_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue) { - attsHandleValueIndNtf(connId, handle, valueLen, pValue, ATT_PDU_VALUE_NTF, FALSE); + attsHandleValueIndNtf(connId, handle, ATT_BEARER_SLOT_ID, valueLen, pValue, ATT_PDU_VALUE_NTF, FALSE); } /*************************************************************************************************/ @@ -627,7 +633,7 @@ void AttsHandleValueNtf(dmConnId_t connId, uint16_t handle, uint16_t valueLen, u void AttsHandleValueIndZeroCpy(dmConnId_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue) { - attsHandleValueIndNtf(connId, handle, valueLen, pValue, ATT_PDU_VALUE_IND, TRUE); + attsHandleValueIndNtf(connId, handle, ATT_BEARER_SLOT_ID, valueLen, pValue, ATT_PDU_VALUE_IND, TRUE); } /*************************************************************************************************/ @@ -648,5 +654,5 @@ void AttsHandleValueIndZeroCpy(dmConnId_t connId, uint16_t handle, uint16_t valu void AttsHandleValueNtfZeroCpy(dmConnId_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue) { - attsHandleValueIndNtf(connId, handle, valueLen, pValue, ATT_PDU_VALUE_NTF, TRUE); + attsHandleValueIndNtf(connId, handle, ATT_BEARER_SLOT_ID, valueLen, pValue, ATT_PDU_VALUE_NTF, TRUE); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.c index fe5f0f463d0..998e6300d08 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief ATT server main module. + * \file + * + * \brief ATT server main module. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -49,7 +51,7 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket); static void attsConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt); -static void attsMsgCback(wsfMsgHdr_t *pMsg); +void attsMsgCback(wsfMsgHdr_t *pMsg); static void attsL2cCtrlCback(wsfMsgHdr_t *pMsg); /************************************************************************************************** @@ -66,7 +68,7 @@ static const attFcnIf_t attsFcnIf = }; /* Minimum PDU lengths, indexed by method */ -static const uint8_t attsMinPduLen[] = +const uint8_t attsMinPduLen[] = { 0, /* ATT_METHOD_ERR */ ATT_MTU_REQ_LEN, /* ATT_METHOD_MTU */ @@ -84,6 +86,7 @@ static const uint8_t attsMinPduLen[] = 0, /* ATT_METHOD_VALUE_NTF */ 0, /* ATT_METHOD_VALUE_IND */ ATT_VALUE_CNF_LEN, /* ATT_METHOD_VALUE_CNF */ + 0, /* ATT_METHOD_READ_MULT_VAR */ ATT_SIGNED_WRITE_CMD_LEN /* ATT_METHOD_SIGNED_WRITE_CMD */ }; @@ -110,6 +113,7 @@ attsProcFcn_t attsProcFcnTbl[ATT_METHOD_SIGNED_WRITE_CMD+1] = NULL, /* ATT_METHOD_VALUE_NTF */ NULL, /* ATT_METHOD_VALUE_IND */ attsProcValueCnf, /* ATT_METHOD_VALUE_CNF */ + attsProcReadMultiVarReq, /* ATT_METHOD_READ_MULT_VAR */ NULL /* ATT_METHOD_SIGNED_WRITE_CMD */ }; @@ -133,11 +137,11 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) uint8_t method; uint8_t err; attsProcFcn_t procFcn; - attCcb_t *pCcb; + attsCcb_t *pCcb; uint16_t attHandle; /* get connection cb for this handle */ - if ((pCcb = attCcbByHandle(handle)) == NULL) + if ((pCcb = attsCcbByHandle(handle, ATT_BEARER_SLOT_ID)) == NULL) { return; } @@ -155,6 +159,10 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) { method = ATT_METHOD_WRITE_CMD; } + else if (opcode == ATT_PDU_READ_MULT_VAR_REQ) + { + method = ATT_METHOD_READ_MULT_VAR; + } else if (opcode == ATT_PDU_SIGNED_WRITE_CMD) { method = ATT_METHOD_SIGNED_WRITE_CMD; @@ -165,7 +173,7 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) } /* ignore packet if write response is pending. */ - if (pCcb->control & ATT_CCB_STATUS_RSP_PENDING) + if (pCcb->pMainCcb->sccb[ATT_BEARER_SLOT_ID].control & ATT_CCB_STATUS_RSP_PENDING) { if (method != ATT_METHOD_VALUE_CNF) { @@ -188,7 +196,7 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) if (attCb.errTest != ATT_SUCCESS) { BYTES_TO_UINT16(attHandle, pPacket + L2C_PAYLOAD_START + ATT_HDR_LEN); - attsErrRsp(handle, opcode, attHandle, attCb.errTest); + attsErrRsp(pCcb->pMainCcb, ATT_BEARER_SLOT_ID, opcode, attHandle, attCb.errTest); return; } #endif @@ -226,7 +234,7 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) if (err && (opcode != ATT_PDU_MTU_REQ) && (opcode != ATT_PDU_VALUE_CNF) && ((opcode & ATT_PDU_MASK_COMMAND) == 0)) { - attsErrRsp(handle, opcode, attHandle, err); + attsErrRsp(pCcb->pMainCcb, ATT_BEARER_SLOT_ID, opcode, attHandle, err); } } @@ -242,16 +250,23 @@ static void attsDataCback(uint16_t handle, uint16_t len, uint8_t *pPacket) /*************************************************************************************************/ static void attsConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) { + uint8_t i; + /* if connection closed */ if (pDmEvt->hdr.event == DM_CONN_CLOSE_IND) { - /* clear prepare write queue */ - attsClearPrepWrites(pCcb); - - /* stop service discovery idle timer, if running */ - if (DmConnCheckIdle(pCcb->connId) & DM_IDLE_ATTS_DISC) + for (i = 0; i < ATT_BEARER_MAX; i++) { - WsfTimerStop(&pCcb->idleTimer); + attsCcb_t *pAttsCb = &attsCb.ccb[pCcb->connId - 1][i]; + + /* clear prepare write queue */ + attsClearPrepWrites(pAttsCb); + + /* stop service discovery idle timer, if running */ + if (DmConnCheckIdle(pCcb->connId) & DM_IDLE_ATTS_DISC) + { + WsfTimerStop(&pAttsCb->idleTimer); + } } } @@ -268,7 +283,7 @@ static void attsConnCback(attCcb_t *pCcb, dmEvt_t *pDmEvt) * \return None. */ /*************************************************************************************************/ -static void attsMsgCback(wsfMsgHdr_t *pMsg) +void attsMsgCback(wsfMsgHdr_t *pMsg) { /* handle service discovery idle timeout */ if (pMsg->event == ATTS_MSG_IDLE_TIMEOUT) @@ -320,7 +335,7 @@ static void attsL2cCtrlCback(wsfMsgHdr_t *pMsg) * \return None. */ /*************************************************************************************************/ -void attsErrRsp(uint16_t handle, uint8_t opcode, uint16_t attHandle, uint8_t reason) +void attsErrRsp(attCcb_t *pCcb, uint8_t slot, uint8_t opcode, uint16_t attHandle, uint8_t reason) { uint8_t *pBuf; uint8_t *p; @@ -334,7 +349,7 @@ void attsErrRsp(uint16_t handle, uint8_t opcode, uint16_t attHandle, uint8_t rea UINT16_TO_BSTREAM(p, attHandle); UINT8_TO_BSTREAM(p, reason); - L2cDataReq(L2C_CID_ATT, handle, ATT_ERR_RSP_LEN, pBuf); + attL2cDataReq(pCcb, slot, ATT_ERR_RSP_LEN, pBuf); } } @@ -347,11 +362,11 @@ void attsErrRsp(uint16_t handle, uint8_t opcode, uint16_t attHandle, uint8_t rea * \return None. */ /*************************************************************************************************/ -void attsClearPrepWrites(attCcb_t *pCcb) +void attsClearPrepWrites(attsCcb_t *pCcb) { void *pBuf; - while ((pBuf = WsfQueueDeq(&pCcb->prepWriteQueue)) != NULL) + while ((pBuf = WsfQueueDeq(&attsCb.prepWriteQueue[pCcb->connId])) != NULL) { WsfBufFree(pBuf); } @@ -366,17 +381,17 @@ void attsClearPrepWrites(attCcb_t *pCcb) * \return None. */ /*************************************************************************************************/ -void attsDiscBusy(attCcb_t *pCcb) +void attsDiscBusy(attsCcb_t *pCcb) { if (pAttCfg->discIdleTimeout > 0) { /* set channel as busy */ - DmConnSetIdle(pCcb->connId, DM_IDLE_ATTS_DISC, DM_CONN_BUSY); + DmConnSetIdle(pCcb->pMainCcb->connId, DM_IDLE_ATTS_DISC, DM_CONN_BUSY); /* start service discovery idle timer */ pCcb->idleTimer.handlerId = attCb.handlerId; pCcb->idleTimer.msg.event = ATTS_MSG_IDLE_TIMEOUT; - pCcb->idleTimer.msg.param = pCcb->connId; + pCcb->idleTimer.msg.param = pCcb->pMainCcb->connId; WsfTimerStartSec(&pCcb->idleTimer, pAttCfg->discIdleTimeout); } } @@ -414,7 +429,9 @@ void attsProcessDatabaseHashUpdate(secCmacMsg_t *pMsg) pMsg->pPlainText = NULL; } + /* copy in little endian */ + WStrReverse(pMsg->pCiphertext, ATT_DATABASE_HASH_LEN); evt.pValue = pMsg->pCiphertext; /* find GATT database handle */ @@ -424,7 +441,7 @@ void attsProcessDatabaseHashUpdate(secCmacMsg_t *pMsg) if (dbhCharHandle != ATT_HANDLE_NONE) { /* Set hash in service. */ - AttsSetAttr(dbhCharHandle, SEC_CMAC_HASH_LEN, evt.pValue); + AttsSetAttr(dbhCharHandle, ATT_DATABASE_HASH_LEN, evt.pValue); } /* set hash update complete */ @@ -451,7 +468,7 @@ void attsCheckPendDbHashReadRsp(void) uint8_t *pBuf; /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(pCcb->sccb[ATT_BEARER_SLOT_ID].mtu + L2C_PAYLOAD_START)) != NULL) { uint8_t *p; attsAttr_t *pAttr; @@ -475,12 +492,12 @@ void attsCheckPendDbHashReadRsp(void) } else { - attsErrRsp(pCcb->connId, ATT_PDU_READ_TYPE_REQ, pCcb->pPendDbHashRsp->startHandle, ATT_ERR_NOT_FOUND); + attsErrRsp(pCcb, ATT_BEARER_SLOT_ID, ATT_PDU_READ_TYPE_REQ, pCcb->pPendDbHashRsp->startHandle, ATT_ERR_NOT_FOUND); } } else { - attsErrRsp(pCcb->connId, ATT_PDU_READ_TYPE_REQ, pCcb->pPendDbHashRsp->startHandle, ATT_ERR_RESOURCES); + attsErrRsp(pCcb, ATT_BEARER_SLOT_ID, ATT_PDU_READ_TYPE_REQ, pCcb->pPendDbHashRsp->startHandle, ATT_ERR_RESOURCES); } /* Free pending state information. */ @@ -558,6 +575,47 @@ uint16_t attsIsHashableAttr(attsAttr_t *pAttr) return length; } +/*************************************************************************************************/ +/*! + * \brief Return the ATTC connection control block connection ID. + * + * \param connId Connection ID. + * + * \return Pointer to connection control block or NULL if not in use. + */ +/*************************************************************************************************/ +attsCcb_t *attsCcbByConnId(dmConnId_t connId, uint8_t slot) +{ + if (DmConnInUse(connId)) + { + return &attsCb.ccb[connId - 1][slot]; + } + + ATT_TRACE_WARN1("atts ccb not in use: %d", connId); + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Return the connection control block for the given handle. + * + * \param handle The connection handle. + * + * \return Pointer to connection control block or NULL if not found. + */ +/*************************************************************************************************/ +attsCcb_t *attsCcbByHandle(uint16_t handle, uint8_t slot) +{ + dmConnId_t connId; + + if ((connId = DmConnIdByHandle(handle)) != DM_CONN_ID_NONE) + { + return &attsCb.ccb[connId - 1][slot]; + } + + return NULL; +} + /*************************************************************************************************/ /*! * \brief Initialize ATT server. @@ -567,11 +625,28 @@ uint16_t attsIsHashableAttr(attsAttr_t *pAttr) /*************************************************************************************************/ void AttsInit(void) { + uint8_t i, j; + attsCcb_t *pCcb; + /* Initialize control block */ WSF_QUEUE_INIT(&attsCb.groupQueue); attsCb.pInd = &attFcnDefault; attsCb.signMsgCback = (attMsgHandler_t) attEmptyHandler; + for (i = 0; i < DM_CONN_MAX; i++) + { + for (j = 0; j < ATT_BEARER_MAX; j++) + { + pCcb = &attsCb.ccb[i][j]; + + /* set pointer to main CCB */ + pCcb->pMainCcb = &attCb.ccb[i]; + + pCcb->connId = i + 1; + pCcb->slot = j; + } + } + /* set up callback interfaces */ attCb.pServer = &attsFcnIf; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.h index bdc4a08f83e..5c46da8b79d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT server main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT server main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef ATTS_MAIN_H @@ -54,8 +56,8 @@ enum /* API parameters */ typedef struct { - uint16_t len; - uint16_t handle; + uint16_t len; + uint16_t handle; } attsPktParam_t; /* verify attsPktParam_t will work in data buffer format described above */ @@ -64,25 +66,23 @@ WSF_CT_ASSERT(sizeof(attsPktParam_t) <= L2C_PAYLOAD_START); /* API message structure */ typedef struct { - wsfMsgHdr_t hdr; - attsPktParam_t *pPkt; + wsfMsgHdr_t hdr; + attsPktParam_t *pPkt; + uint8_t slot; } attsApiMsg_t; -/* Connection control block for indications/notifications */ +/* ATTS connection control block */ typedef struct { - wsfTimer_t outIndTimer; /* Outstanding indication timer */ - attCcb_t *pMainCcb; /* Pointer to ATT main CCB */ - uint16_t outIndHandle; /* Waiting for confirm from peer for this indication handle */ - uint16_t pendIndHandle; /* Callback to application pending for this indication handle */ + wsfTimer_t outIndTimer; /* Outstanding indication timer */ + attCcb_t *pMainCcb; /* Pointer to ATT main CCB */ + wsfTimer_t idleTimer; /* service discovery idle timer */ + dmConnId_t connId; /* DM connection ID */ + uint8_t slot; /* ATT/EATT slot ID */ + uint16_t outIndHandle; /* Waiting for confirm from peer for this indication handle */ + uint16_t pendIndHandle; /* Callback to application pending for this indication handle */ uint16_t pendNtfHandle[ATT_NUM_SIMUL_NTF]; /* Callback to application pending for this notification handle */ -} attsIndCcb_t; - -/* Control block for indications/notifications */ -typedef struct -{ - attsIndCcb_t ccb[DM_CONN_MAX]; -} attsIndCb_t; +} attsCcb_t; /* Client characteristic configuration descriptor callback type * @@ -98,22 +98,24 @@ typedef uint8_t (*attsCccFcn_t)(dmConnId_t connId, uint8_t method, uint16_t hand /* Main control block of the ATTS subsystem */ typedef struct { - wsfQueue_t groupQueue; /* Queue of attribute groups */ - attFcnIf_t const *pInd; /* Indication callback interface */ - attMsgHandler_t signMsgCback; /* Signed data callback interface */ - attsAuthorCback_t authorCback; /* Authorization callback */ - attsCccFcn_t cccCback; /* CCC callback */ + attsCcb_t ccb[DM_CONN_MAX][ATT_BEARER_MAX]; /* Connection slot control block */ + wsfQueue_t prepWriteQueue[DM_CONN_MAX]; /* Connection prepare write queue */ + wsfQueue_t groupQueue; /* Queue of attribute groups */ + attFcnIf_t const *pInd; /* Indication callback interface */ + attMsgHandler_t signMsgCback; /* Signed data callback interface */ + attsAuthorCback_t authorCback; /* Authorization callback */ + attsCccFcn_t cccCback; /* CCC callback */ } attsCb_t; /* PDU processing function type */ -typedef void (*attsProcFcn_t)(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +typedef void (*attsProcFcn_t)(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); /* CSF Control block */ typedef struct { - attsCsfRec_t attsCsfTable[DM_CONN_MAX]; /* connected clients' supported features record table. */ - attsCsfWriteCback_t writeCback; /* Write callback. */ - uint8_t isHashUpdating; /* Database hash update status. */ + attsCsfRec_t attsCsfTable[DM_CONN_MAX]; /* connected clients' supported features record table. */ + attsCsfWriteCback_t writeCback; /* Write callback. */ + uint8_t isHashUpdating; /* Database hash update status. */ } attsCsfCb_t; /************************************************************************************************** @@ -123,9 +125,6 @@ typedef struct /* PDU processing function lookup table, indexed by method */ extern attsProcFcn_t attsProcFcnTbl[ATT_METHOD_SIGNED_WRITE_CMD+1]; -/* Control block for indications/notifications */ -extern attsIndCb_t attsIndCb; - /* Control block */ extern attsCb_t attsCb; @@ -133,8 +132,11 @@ extern attsCb_t attsCb; Function Declarations **************************************************************************************************/ -void attsErrRsp(uint16_t handle, uint8_t opcode, uint16_t attHandle, uint8_t reason); -void attsClearPrepWrites(attCcb_t *pCcb); +attsCcb_t *attsCcbByConnId(dmConnId_t connId, uint8_t slot); +attsCcb_t *attsCcbByHandle(uint16_t handle, uint8_t slot); + +void attsErrRsp(attCcb_t *pCcb, uint8_t slot, uint8_t opcode, uint16_t attHandle, uint8_t reason); +void attsClearPrepWrites(attsCcb_t *pCcb); bool_t attsUuidCmp(attsAttr_t *pAttr, uint8_t uuidLen, uint8_t *pUuid); bool_t attsUuid16Cmp(uint8_t *pUuid16, uint8_t uuidLen, uint8_t *pUuid); attsAttr_t *attsFindByHandle(uint16_t handle, attsGroup_t **pAttrGroup); @@ -142,29 +144,35 @@ uint16_t attsFindInRange(uint16_t startHandle, uint16_t endHandle, attsAttr_t ** uint16_t attsFindUuidInRange(uint16_t startHandle, uint16_t endHandle, uint8_t uuidLen, uint8_t *pUuid, attsAttr_t **pAttr, attsGroup_t **pAttrGroup); uint8_t attsPermissions(dmConnId_t connId, uint8_t permit, uint16_t handle, uint8_t permissions); -void attsDiscBusy(attCcb_t *pCcb); +void attsDiscBusy(attsCcb_t *pCcb); void attsCheckPendDbHashReadRsp(void); void attsProcessDatabaseHashUpdate(secCmacMsg_t *pMsg); uint16_t attsIsHashableAttr(attsAttr_t *pAttr); - -void attsProcMtuReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); -void attsProcValueCnf(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsMsgCback(wsfMsgHdr_t *pMsg); + +void attsProcMtuReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcFindInfoReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcFindTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadBlobReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadMultReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadGroupTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcWrite(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcPrepWriteReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcExecWriteReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcValueCnf(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); +void attsProcReadMultiVarReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket); uint8_t attsCsfActClientState(uint16_t handle, uint8_t opcode, uint8_t *pPacket); uint8_t attsCsfIsClientChangeAware(dmConnId_t connId, uint16_t handle); void attsCsfSetHashUpdateStatus(bool_t isUpdating); uint8_t attsCsfGetHashUpdateStatus(void); +void attsIndNtfCallback(dmConnId_t connId, attsCcb_t *pCcb, uint8_t status); +void attsHandleValueIndNtf(dmConnId_t connId, uint16_t handle, uint8_t slot, uint16_t valueLen, + uint8_t *pValue, uint8_t opcode, bool_t zeroCpy); + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_proc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_proc.c index 360f13d46cc..455950e73bd 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_proc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_proc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT server mandatory PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT server mandatory PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,6 +32,7 @@ #include "att_api.h" #include "att_main.h" #include "atts_main.h" +#include "svc_core.h" /*************************************************************************************************/ /*! @@ -232,39 +235,53 @@ uint8_t attsPermissions(dmConnId_t connId, uint8_t permit, uint16_t handle, uint * \return None. */ /*************************************************************************************************/ -void attsProcMtuReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcMtuReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *p; uint16_t mtu; uint16_t localMtu; uint8_t *pRsp; + uint8_t features; - p = pPacket + L2C_PAYLOAD_START + ATT_HDR_LEN; - - /* parse mtu */ - BYTES_TO_UINT16(mtu, p); + /* Verify Server supported features permits MTU exchange */ + AttsCsfGetFeatures(pCcb->connId, &features, sizeof(uint8_t)); + + ATT_TRACE_WARN1("attsProcMtuReq features 0x%02x", features); - /* verify */ - if (mtu < ATT_DEFAULT_MTU) + if (features & ATTS_CSF_EATT_BEARER) { - mtu = ATT_DEFAULT_MTU; + /* Client set the EATT supported feature. MTU Exchange not permitted */ + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_MTU_REQ, 0, ATT_ERR_NOT_SUP); } + else + { + p = pPacket + L2C_PAYLOAD_START + ATT_HDR_LEN; - /* get desired MTU */ - localMtu = WSF_MIN(pAttCfg->mtu, (HciGetMaxRxAclLen() - L2C_HDR_LEN)); + /* parse mtu */ + BYTES_TO_UINT16(mtu, p); - /* send response */ - if ((pRsp = attMsgAlloc(L2C_PAYLOAD_START + ATT_MTU_RSP_LEN)) != NULL) - { - p = pRsp + L2C_PAYLOAD_START; - UINT8_TO_BSTREAM(p, ATT_PDU_MTU_RSP); - UINT16_TO_BSTREAM(p, localMtu); + /* verify */ + if (mtu < ATT_DEFAULT_MTU) + { + mtu = ATT_DEFAULT_MTU; + } - L2cDataReq(L2C_CID_ATT, pCcb->handle, ATT_MTU_RSP_LEN, pRsp); - } + /* get desired MTU */ + localMtu = WSF_MIN(pAttCfg->mtu, (HciGetMaxRxAclLen() - L2C_HDR_LEN)); + + /* send response */ + if ((pRsp = attMsgAlloc(L2C_PAYLOAD_START + ATT_MTU_RSP_LEN)) != NULL) + { + p = pRsp + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_MTU_RSP); + UINT16_TO_BSTREAM(p, localMtu); + + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, ATT_MTU_RSP_LEN, pRsp); + } - /* set mtu for the connection */ - attSetMtu(pCcb, mtu, localMtu); + /* set mtu for the connection */ + attSetMtu(pCcb->pMainCcb, pCcb->slot, mtu, localMtu); + } } /*************************************************************************************************/ @@ -278,7 +295,7 @@ void attsProcMtuReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcFindInfoReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -287,6 +304,7 @@ void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint16_t endHandle; uint16_t handle; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handles */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -302,7 +320,7 @@ void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (!err) { /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(mtu + L2C_PAYLOAD_START)) != NULL) { p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_FIND_INFO_RSP); @@ -335,7 +353,7 @@ void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { /* check if result fits */ if ((p + ATT_16_UUID_LEN + sizeof(uint16_t)) <= - (pBuf + pCcb->mtu + L2C_PAYLOAD_START)) + (pBuf + mtu + L2C_PAYLOAD_START)) { /* copy result */ UINT16_TO_BSTREAM(p, handle); @@ -382,11 +400,11 @@ void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if no error send response, else send error */ if (!err) { - L2cDataReq(L2C_CID_ATT, pCcb->handle, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); } else { - attsErrRsp(pCcb->handle, ATT_PDU_FIND_INFO_REQ, startHandle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_FIND_INFO_REQ, startHandle, err); } } @@ -401,7 +419,7 @@ void attsProcFindInfoReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcReadReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -410,6 +428,7 @@ void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint16_t handle; uint16_t readLen; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handle */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -419,26 +438,26 @@ void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) { /* verify permissions */ - if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions)) == ATT_SUCCESS) { /* call read callback if desired */ if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) { - err = (*pGroup->readCback)(pCcb->connId, handle, ATT_PDU_READ_REQ, 0, pAttr); + err = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_REQ, 0, pAttr); } /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - err = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); } if (err == ATT_SUCCESS) { /* determine length of data to read */ - readLen = (*pAttr->pLen < (pCcb->mtu - ATT_READ_RSP_LEN)) ? - *pAttr->pLen : (pCcb->mtu - ATT_READ_RSP_LEN); + readLen = (*pAttr->pLen < (mtu - ATT_READ_RSP_LEN)) ? + *pAttr->pLen : (mtu - ATT_READ_RSP_LEN); /* Allocate response buffer */ if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + ATT_READ_RSP_LEN + readLen)) != NULL) @@ -448,7 +467,7 @@ void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) UINT8_TO_BSTREAM(p, ATT_PDU_READ_RSP); memcpy(p, pAttr->pValue, readLen); - L2cDataReq(L2C_CID_ATT, pCcb->handle, (ATT_READ_RSP_LEN + readLen), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (ATT_READ_RSP_LEN + readLen), pBuf); } } } @@ -461,7 +480,110 @@ void attsProcReadReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (err) { - attsErrRsp(pCcb->handle, ATT_PDU_READ_REQ, handle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_REQ, handle, err); } } +/*************************************************************************************************/ +/*! + * \brief Process a read multi variable length request PDU. + * + * \param pCcb Connection control block. + * \param len The length of the L2CAP payload data in pPacket. + * \param pPacket A buffer containing the packet. + * + * \return None. + */ +/*************************************************************************************************/ +void attsProcReadMultiVarReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +{ + uint8_t *pBuf; + uint8_t *p; + attsAttr_t *pAttr; + attsGroup_t *pGroup; + uint16_t handle = ATT_HANDLE_NONE; + uint16_t rspLen = 0; + uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; + const uint8_t hdrLen = L2C_PAYLOAD_START + ATT_HDR_LEN; + + pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; + len -= ATT_HDR_LEN; + + if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + mtu)) != NULL) + { + p = pBuf + hdrLen; + + while (len > 0) + { + /* parse handle */ + BSTREAM_TO_UINT16(handle, pPacket); + len -= sizeof(uint16_t); + + /* find attribute */ + if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) + { + /* verify permissions */ + if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, + handle, pAttr->permissions)) == ATT_SUCCESS) + { + /* call read callback if desired */ + if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) + { + err = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_MULT_VAR_REQ, 0, pAttr); + } + /* else check if CCC */ + else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) + { + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + } + + if (err == ATT_SUCCESS) + { + /* determine length of data to read */ + uint16_t readLen = (*pAttr->pLen < (mtu - rspLen - hdrLen)) ? + *pAttr->pLen : (mtu - rspLen - hdrLen); + + UINT16_TO_BSTREAM(p, readLen); + memcpy(p, pAttr->pValue, readLen); + p += readLen; + rspLen += readLen + sizeof(uint16_t); + + /* if truncating, then we are done */ + if (readLen < *pAttr->pLen) + { + break; + } + } + else + { + break; + } + } + } + else + { + err = ATT_ERR_HANDLE; + break; + } + } + + if (err == ATT_SUCCESS) + { + /* complete and send PDU */ + p = pBuf + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, ATT_PDU_READ_MULT_VAR_RSP); + + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (ATT_READ_MULT_VAR_RSP_LEN + rspLen), pBuf); + } + else + { + AttMsgFree(pBuf, ATT_PDU_READ_MULT_VAR_RSP); + } + } + + if (err) + { + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_MULT_VAR_REQ, handle, err); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_read.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_read.c index aa7620d26bb..4e168d05259 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_read.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_read.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT server optional read PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT server optional read PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -168,7 +170,7 @@ uint16_t attsFindServiceGroupEnd(uint16_t startHandle) * \return None. */ /*************************************************************************************************/ -void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcReadBlobReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -178,6 +180,7 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint16_t offset; uint16_t readLen; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handle and offset */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -188,7 +191,7 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) { /* verify permissions */ - if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions)) != ATT_SUCCESS) { /* err has been set; fail */ @@ -204,19 +207,19 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) { - err = (*pGroup->readCback)(pCcb->connId, handle, ATT_PDU_READ_BLOB_REQ, offset, pAttr); + err = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_BLOB_REQ, offset, pAttr); } /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - err = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); } if (err == ATT_SUCCESS) { /* determine length of data to read */ - readLen = ((*pAttr->pLen - offset) < (pCcb->mtu - ATT_READ_BLOB_RSP_LEN)) ? - (*pAttr->pLen - offset) : (pCcb->mtu - ATT_READ_BLOB_RSP_LEN); + readLen = ((*pAttr->pLen - offset) < (mtu - ATT_READ_BLOB_RSP_LEN)) ? + (*pAttr->pLen - offset) : (mtu - ATT_READ_BLOB_RSP_LEN); /* Allocate response buffer */ if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + ATT_READ_BLOB_RSP_LEN + readLen)) != NULL) @@ -226,7 +229,7 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) UINT8_TO_BSTREAM(p, ATT_PDU_READ_BLOB_RSP); memcpy(p, (pAttr->pValue + offset), readLen); - L2cDataReq(L2C_CID_ATT, pCcb->handle, (ATT_READ_BLOB_RSP_LEN + readLen), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (ATT_READ_BLOB_RSP_LEN + readLen), pBuf); } } } @@ -239,7 +242,7 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (err) { - attsErrRsp(pCcb->handle, ATT_PDU_READ_BLOB_REQ, handle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_BLOB_REQ, handle, err); } } @@ -254,7 +257,7 @@ void attsProcReadBlobReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcFindTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -266,6 +269,7 @@ void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint16_t handle; uint16_t nextHandle; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handles and uuid; pPacket then points to the value in the request */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -286,7 +290,7 @@ void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (!err) { /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(mtu + L2C_PAYLOAD_START)) != NULL) { p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_FIND_TYPE_RSP); @@ -315,7 +319,7 @@ void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) } /* copy result into response buffer; first check if it fits */ - if ((p + (sizeof(uint16_t) * 2)) <= (pBuf + pCcb->mtu + L2C_PAYLOAD_START)) + if ((p + (sizeof(uint16_t) * 2)) <= (pBuf + mtu + L2C_PAYLOAD_START)) { UINT16_TO_BSTREAM(p, handle); UINT16_TO_BSTREAM(p, nextHandle); @@ -362,11 +366,11 @@ void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if no error send response, else send error */ if (!err) { - L2cDataReq(L2C_CID_ATT, pCcb->handle, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); } else { - attsErrRsp(pCcb->handle, ATT_PDU_FIND_TYPE_REQ, startHandle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_FIND_TYPE_REQ, startHandle, err); } } @@ -381,10 +385,10 @@ void attsProcFindTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcReadTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { - uint8_t *pBuf; - uint8_t *p; + uint8_t *pBuf = NULL; + uint8_t *p = NULL; attsAttr_t *pAttr; attsGroup_t *pGroup; uint16_t startHandle; @@ -394,6 +398,7 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint8_t attLen; uint8_t cbackErr = ATT_SUCCESS; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handles; pPacket then points to the uuid */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -423,7 +428,7 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) err = ATT_ERR_NOT_FOUND; } /* check permissions */ - else if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + else if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions)) != ATT_SUCCESS) { /* err is set above */ @@ -432,12 +437,12 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) else if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) { - err = (*pGroup->readCback)(pCcb->connId, handle, ATT_PDU_READ_TYPE_REQ, 0, pAttr); + err = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_TYPE_REQ, 0, pAttr); } /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - err = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); } if (err == ATT_SUCCESS) @@ -448,29 +453,29 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((memcmp(pPacket, attGattDbhChUuid, ATT_16_UUID_LEN) == 0) && attsCsfGetHashUpdateStatus()) { /* Store info and return */ - pCcb->pPendDbHashRsp = WsfBufAlloc(sizeof(attPendDbHashRsp_t)); - if (pCcb->pPendDbHashRsp) + pCcb->pMainCcb->pPendDbHashRsp = WsfBufAlloc(sizeof(attPendDbHashRsp_t)); + if (pCcb->pMainCcb->pPendDbHashRsp) { - pCcb->pPendDbHashRsp->startHandle = startHandle; - pCcb->pPendDbHashRsp->handle = handle; + pCcb->pMainCcb->pPendDbHashRsp->startHandle = startHandle; + pCcb->pMainCcb->pPendDbHashRsp->handle = handle; } else { - attsErrRsp(pCcb->handle, ATT_PDU_READ_TYPE_REQ, startHandle, ATT_ERR_RESOURCES); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_TYPE_REQ, startHandle, ATT_ERR_RESOURCES); } return; } /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(mtu + L2C_PAYLOAD_START)) != NULL) { p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_READ_TYPE_RSP); /* get length of this first attribute */ - attLen = (*pAttr->pLen < (pCcb->mtu - ATT_READ_TYPE_RSP_LEN - sizeof(uint16_t))) ? - *pAttr->pLen : (pCcb->mtu - ATT_READ_TYPE_RSP_LEN - sizeof(uint16_t)); + attLen = (*pAttr->pLen < (mtu - ATT_READ_TYPE_RSP_LEN - sizeof(uint16_t))) ? + *pAttr->pLen : (mtu - ATT_READ_TYPE_RSP_LEN - sizeof(uint16_t)); /* set length parameter in response message */ UINT8_TO_BSTREAM(p, attLen + sizeof(uint16_t)); @@ -489,12 +494,12 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) { - cbackErr = (*pGroup->readCback)(pCcb->connId, handle, ATT_PDU_READ_TYPE_REQ, 0, pAttr); + cbackErr = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_TYPE_REQ, 0, pAttr); } /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - cbackErr = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + cbackErr = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); } /* verify no error from read callback @@ -503,11 +508,11 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) */ if ((cbackErr == ATT_SUCCESS) && (*pAttr->pLen == attLen) && - (attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + (attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions) == ATT_SUCCESS)) { /* copy result into response buffer; first check if it fits */ - if ((p + attLen + sizeof(uint16_t)) <= (pBuf + pCcb->mtu + L2C_PAYLOAD_START)) + if ((p + attLen + sizeof(uint16_t)) <= (pBuf + mtu + L2C_PAYLOAD_START)) { UINT16_TO_BSTREAM(p, handle); memcpy(p, pAttr->pValue, attLen); @@ -549,11 +554,11 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if no error send response, else send error */ if (!err) { - L2cDataReq(L2C_CID_ATT, pCcb->handle, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); } else { - attsErrRsp(pCcb->handle, ATT_PDU_READ_TYPE_REQ, startHandle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_TYPE_REQ, startHandle, err); } } @@ -568,7 +573,7 @@ void attsProcReadTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcReadMultReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -578,6 +583,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint16_t handle = ATT_HANDLE_NONE; uint16_t readLen; uint8_t err = ATT_SUCCESS; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* points to end of payload */ pEnd = pPacket + L2C_PAYLOAD_START + len; @@ -586,7 +592,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(mtu + L2C_PAYLOAD_START)) != NULL) { p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_READ_MULT_RSP); @@ -605,7 +611,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) } /* verify permissions */ - if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions)) != ATT_SUCCESS) { break; @@ -615,7 +621,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr->settings & ATTS_SET_READ_CBACK) && (pGroup->readCback != NULL)) { - err = (*pGroup->readCback)(pCcb->connId, handle, ATT_PDU_READ_MULT_REQ, 0, pAttr); + err = (*pGroup->readCback)(pCcb->pMainCcb->connId, handle, ATT_PDU_READ_MULT_REQ, 0, pAttr); if (err != ATT_SUCCESS) { break; @@ -624,17 +630,17 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - err = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_READ, handle, pAttr->pValue); if (err != ATT_SUCCESS) { break; } } - if (p < (pBuf + pCcb->mtu + L2C_PAYLOAD_START)) + if (p < (pBuf + mtu + L2C_PAYLOAD_START)) { /* calculate remaining space in response buffer */ - readLen = (pBuf + pCcb->mtu + L2C_PAYLOAD_START) - p; + readLen = (pBuf + mtu + L2C_PAYLOAD_START) - p; /* actual length is minimum of remaining space and attribute length */ readLen = (*pAttr->pLen < readLen) ? *pAttr->pLen : readLen; @@ -654,7 +660,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if no error send response, else send error */ if (!err) { - L2cDataReq(L2C_CID_ATT, pCcb->handle, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); } else { @@ -664,7 +670,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) WsfMsgFree(pBuf); } - attsErrRsp(pCcb->handle, ATT_PDU_READ_MULT_REQ, handle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_MULT_REQ, handle, err); } } @@ -679,7 +685,7 @@ void attsProcReadMultReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcReadGroupTypeReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf = NULL; uint8_t *p = NULL; @@ -692,6 +698,7 @@ void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) uint8_t attLen; uint8_t err = ATT_SUCCESS; uint8_t primSvcUuid[ATT_16_UUID_LEN] = {UINT16_TO_BYTES(ATT_UUID_PRIMARY_SERVICE)}; + uint16_t mtu = pCcb->pMainCcb->sccb[pCcb->slot].mtu; /* parse handles; pPacket then points to the uuid */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; @@ -725,7 +732,7 @@ void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) err = ATT_ERR_NOT_FOUND; } /* check permissions */ - else if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + else if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions)) != ATT_SUCCESS) { startHandle = handle; /* this handle is returned in error response */ @@ -733,14 +740,14 @@ void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) else { /* allocate max size buffer for response */ - if ((pBuf = attMsgAlloc(pCcb->mtu + L2C_PAYLOAD_START)) != NULL) + if ((pBuf = attMsgAlloc(mtu + L2C_PAYLOAD_START)) != NULL) { p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_READ_GROUP_TYPE_RSP); /* get length of this first attribute */ - attLen = (*pAttr->pLen < (pCcb->mtu - ATT_READ_GROUP_TYPE_RSP_LEN - (2 * sizeof(uint16_t)))) ? - *pAttr->pLen : (pCcb->mtu - ATT_READ_GROUP_TYPE_RSP_LEN - (2 * sizeof(uint16_t))); + attLen = (*pAttr->pLen < (mtu - ATT_READ_GROUP_TYPE_RSP_LEN - (2 * sizeof(uint16_t)))) ? + *pAttr->pLen : (mtu - ATT_READ_GROUP_TYPE_RSP_LEN - (2 * sizeof(uint16_t))); /* set length parameter in response message */ UINT8_TO_BSTREAM(p, attLen + (2 * sizeof(uint16_t))); @@ -782,12 +789,12 @@ void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * verify attribute permissions */ if ((*pAttr->pLen == attLen) && - (attsPermissions(pCcb->connId, ATTS_PERMIT_READ, + (attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_READ, handle, pAttr->permissions) == ATT_SUCCESS)) { /* copy result into response buffer; first check if it fits */ if ((p + attLen + (2 * sizeof(uint16_t))) <= - (pBuf + pCcb->mtu + L2C_PAYLOAD_START)) + (pBuf + mtu + L2C_PAYLOAD_START)) { UINT16_TO_BSTREAM(p, handle); handle = attsFindServiceGroupEnd(handle); @@ -822,10 +829,10 @@ void attsProcReadGroupTypeReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* if no error send response, else send error */ if (!err) { - L2cDataReq(L2C_CID_ATT, pCcb->handle, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (p - (pBuf + L2C_PAYLOAD_START)), pBuf); } else { - attsErrRsp(pCcb->handle, ATT_PDU_READ_GROUP_TYPE_REQ, startHandle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_READ_GROUP_TYPE_REQ, startHandle, err); } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c index 9c0dc8378e4..5cadd92e465 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT server signed PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT server signed PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -57,7 +59,6 @@ typedef struct uint32_t signCounter; /* sign counter for this connection */ uint8_t *pCsrk; /* signing key for this connection */ attsSignBuf_t *pBuf; /* current data being processed */ - bool_t authenticated; /* Indicate if the CSRK is authenticated or not */ } attsSignCcb_t; /* ATTS signed PDU control block */ @@ -126,10 +127,14 @@ static void attsSignedWriteStart(attsSignCcb_t *pCcb, attsSignBuf_t *pBuf) WsfBufFree(pCmacTxt); } } + else + { + /* no CSRK */ + ATT_TRACE_WARN0("ATTS CSRK not set"); + } - /* no CSRK-- free buffer */ + /* free buffer */ WsfBufFree(pBuf); - ATT_TRACE_WARN0("ATTS CSRK not set"); } /*************************************************************************************************/ @@ -143,7 +148,7 @@ static void attsSignedWriteStart(attsSignCcb_t *pCcb, attsSignBuf_t *pBuf) * \return None. */ /*************************************************************************************************/ -static void attsProcSignedWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +static void attsProcSignedWrite(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *p; attsAttr_t *pAttr; @@ -161,69 +166,53 @@ static void attsProcSignedWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* find attribute */ if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) { - /* verify signed write is permitted */ - if ((pAttr->settings & ATTS_SET_ALLOW_SIGNED) == 0) + /* verify permissions */ + if (attsPermissions(pCcb->connId, ATTS_PERMIT_WRITE, handle, pAttr->permissions) != ATT_SUCCESS) { return; } - - /* verify that csrk is present */ - if (attsSignCcbByConnId(pCcb->connId)->pCsrk == NULL) { - return; - } - - /* verify basic permissions */ - if ((pAttr->permissions & (ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC)) == 0) - { - return; - } - - /* verify authentication */ - if ((pAttr->permissions & ATTS_PERMIT_WRITE_AUTH) && - (attsSignCcbByConnId(pCcb->connId)->authenticated == 0)) + /* verify signed write is permitted */ + else if ((pAttr->settings & ATTS_SET_ALLOW_SIGNED) == 0) { return; } - - /* Note: authorization not verified at this stage as it is reserved for lesc - writes; authorization occurs latter when the write cb is called */ - /* verify write length, fixed length */ - if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) && + else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) && (writeLen != pAttr->maxLen)) { return; } - /* verify write length, variable length */ - if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) != 0) && + else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) != 0) && (writeLen > pAttr->maxLen)) { return; } - - /* allocate buffer to store packet and parameters */ - if ((pBuf = WsfBufAlloc(sizeof(attsSignBuf_t) - 1 + len)) != NULL) + else { - /* initialize buffer */ - pBuf->pCcb = pCcb; - pBuf->handle = handle; - pBuf->writeLen = writeLen; - pBuf->connId = pCcb->connId; - memcpy(pBuf->packet, (pPacket + L2C_PAYLOAD_START), len); + /* allocate buffer to store packet and parameters */ + if ((pBuf = WsfBufAlloc(sizeof(attsSignBuf_t) - 1 + len)) != NULL) + { + /* initialize buffer */ + pBuf->pCcb = pCcb->pMainCcb; + pBuf->handle = handle; + pBuf->writeLen = writeLen; + pBuf->connId = pCcb->connId; + memcpy(pBuf->packet, (pPacket + L2C_PAYLOAD_START), len); - /* check if a signed write is already in progress */ - pSignCcb = attsSignCcbByConnId(pCcb->connId); + /* check if a signed write is already in progress */ + pSignCcb = attsSignCcbByConnId(pCcb->connId); - if (pSignCcb->pBuf != NULL) - { - /* signed write in progress; queue packet */ - WsfQueueEnq(&attsSignCb.msgQueue, pBuf); - } - else - { - /* start signed data processing */ - attsSignedWriteStart(pSignCcb, pBuf); + if (pSignCcb->pBuf != NULL) + { + /* signed write in progress; queue packet */ + WsfQueueEnq(&attsSignCb.msgQueue, pBuf); + } + else + { + /* start signed data processing */ + attsSignedWriteStart(pSignCcb, pBuf); + } } } } @@ -247,7 +236,7 @@ static void attsSignMsgCback(secCmacMsg_t *pMsg) uint32_t signCounter; if (pMsg->hdr.event == ATTS_MSG_SIGN_CMAC_CMPL) - { + { uint8_t signature[ATT_CMAC_RESULT_LEN] = {0}; pCcb = attsSignCcbByConnId((dmConnId_t) pMsg->hdr.param); @@ -353,15 +342,13 @@ void AttsSignInit(void) * * \param connId DM connection ID. * \param pCsrk Pointer to data signing key (CSRK). - * \param authenticated True if CSRK is authenticated and false otherwise. * * \return None. */ /*************************************************************************************************/ -void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk, bool_t authenticated) +void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk) { attsSignCcbByConnId(connId)->pCsrk = pCsrk; - attsSignCcbByConnId(connId)->authenticated = authenticated; } /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_write.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_write.c index 0b60bc59d7a..1b41582c581 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_write.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_write.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief ATT server write PDU processing functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief ATT server write PDU processing functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -55,7 +57,7 @@ typedef struct attsPrepWrite_tag * \return ATT_SUCCESS or failure status. */ /*************************************************************************************************/ -static uint8_t attsExecPrepWrite(attCcb_t *pCcb, attsPrepWrite_t *pPrep) +static uint8_t attsExecPrepWrite(attsCcb_t *pCcb, attsPrepWrite_t *pPrep) { uint8_t *p; attsAttr_t *pAttr; @@ -117,7 +119,7 @@ static uint8_t attsExecPrepWrite(attCcb_t *pCcb, attsPrepWrite_t *pPrep) * \return None. */ /*************************************************************************************************/ -void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcWrite(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -138,7 +140,7 @@ void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) { /* verify permissions */ - if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_WRITE, + if ((err = attsPermissions(pCcb->pMainCcb->connId, ATTS_PERMIT_WRITE, handle, pAttr->permissions)) != ATT_SUCCESS) { /* err has been set; fail */ @@ -161,13 +163,13 @@ void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if ((pAttr->settings & ATTS_SET_WRITE_CBACK) && (pGroup->writeCback != NULL)) { - err = (*pGroup->writeCback)(pCcb->connId, handle, opcode, 0, writeLen, + err = (*pGroup->writeCback)(pCcb->pMainCcb->connId, handle, opcode, 0, writeLen, pPacket, pAttr); } /* else check if CCC */ else if ((pAttr->settings & ATTS_SET_CCC) && (attsCb.cccCback != NULL)) { - err = (*attsCb.cccCback)(pCcb->connId, ATT_METHOD_WRITE, handle, pPacket); + err = (*attsCb.cccCback)(pCcb->pMainCcb->connId, ATT_METHOD_WRITE, handle, pPacket); } else { @@ -190,7 +192,7 @@ void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_RSP); - L2cDataReq(L2C_CID_ATT, pCcb->handle, ATT_WRITE_RSP_LEN, pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, ATT_WRITE_RSP_LEN, pBuf); } } } @@ -207,11 +209,11 @@ void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (err == ATT_RSP_PENDING) { /* set response pending */ - pCcb->control |= ATT_CCB_STATUS_RSP_PENDING; + pCcb->pMainCcb->sccb[pCcb->slot].control |= ATT_CCB_STATUS_RSP_PENDING; } else { - attsErrRsp(pCcb->handle, ATT_PDU_WRITE_REQ, handle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_WRITE_REQ, handle, err); } } } @@ -227,13 +229,13 @@ void attsProcWrite(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcPrepWriteReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; attsAttr_t *pAttr; attsGroup_t *pGroup; - attsPrepWrite_t *pPrep; + attsPrepWrite_t *pPrep = NULL; uint16_t handle; uint16_t offset; uint16_t writeLen; @@ -269,7 +271,7 @@ void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) err = ATT_ERR_LENGTH; } /* verify prepare write queue limit not reached */ - else if (WsfQueueCount(&pCcb->prepWriteQueue) >= pAttCfg->numPrepWrites) + else if (WsfQueueCount(&attsCb.prepWriteQueue[pCcb->connId]) >= pAttCfg->numPrepWrites) { err = ATT_ERR_QUEUE_FULL; } @@ -292,7 +294,7 @@ void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) pPrep->handle = handle; pPrep->offset = offset; memcpy(pPrep->packet, pPacket, writeLen); - WsfQueueEnq(&pCcb->prepWriteQueue, pPrep); + WsfQueueEnq(&attsCb.prepWriteQueue[pCcb->connId], pPrep); /* allocate response buffer */ if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + ATT_PREP_WRITE_RSP_LEN + writeLen)) != NULL) @@ -304,13 +306,13 @@ void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) UINT16_TO_BSTREAM(p, offset); memcpy(p, pPacket, writeLen); - L2cDataReq(L2C_CID_ATT, pCcb->handle, (ATT_PREP_WRITE_RSP_LEN + writeLen), pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, (ATT_PREP_WRITE_RSP_LEN + writeLen), pBuf); } } if (err) { - attsErrRsp(pCcb->handle, ATT_PDU_PREP_WRITE_REQ, handle, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_PREP_WRITE_REQ, handle, err); } } @@ -325,7 +327,7 @@ void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) * \return None. */ /*************************************************************************************************/ -void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) +void attsProcExecWriteReq(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; @@ -346,7 +348,7 @@ void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) else if (*pPacket == ATT_EXEC_WRITE_ALL) { /* iterate over prepare write queue and verify offset and length */ - for (pPrep = pCcb->prepWriteQueue.pHead; pPrep != NULL; pPrep = pPrep->pNext) + for (pPrep = attsCb.prepWriteQueue[pCcb->connId].pHead; pPrep != NULL; pPrep = pPrep->pNext) { /* find attribute */ if ((pAttr = attsFindByHandle(pPrep->handle, &pGroup)) != NULL) @@ -375,7 +377,7 @@ void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) if (err == ATT_SUCCESS) { /* for each buffer */ - while ((pPrep = WsfQueueDeq(&pCcb->prepWriteQueue)) != NULL) + while ((pPrep = WsfQueueDeq(&attsCb.prepWriteQueue[pCcb->connId])) != NULL) { /* write buffer */ if ((err = attsExecPrepWrite(pCcb, pPrep)) != ATT_SUCCESS) @@ -398,7 +400,7 @@ void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* send response or error response */ if (err) { - attsErrRsp(pCcb->handle, ATT_PDU_EXEC_WRITE_REQ, 0, err); + attsErrRsp(pCcb->pMainCcb, pCcb->slot, ATT_PDU_EXEC_WRITE_REQ, 0, err); } else { @@ -408,7 +410,7 @@ void attsProcExecWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_EXEC_WRITE_RSP); - L2cDataReq(L2C_CID_ATT, pCcb->handle, ATT_EXEC_WRITE_RSP_LEN, pBuf); + attL2cDataReq(pCcb->pMainCcb, pCcb->slot, ATT_EXEC_WRITE_RSP_LEN, pBuf); } } } @@ -441,11 +443,11 @@ void AttsContinueWriteReq(dmConnId_t connId, uint16_t handle, uint8_t status) } /* clear response pending */ - pCcb->control &= ~ATT_CCB_STATUS_RSP_PENDING; + pCcb->sccb[ATT_BEARER_SLOT_ID].control &= ~ATT_CCB_STATUS_RSP_PENDING; if (status) { - attsErrRsp(pCcb->handle, ATT_PDU_WRITE_REQ, handle, status); + attsErrRsp(pCcb, ATT_BEARER_SLOT_ID, ATT_PDU_WRITE_REQ, handle, status); } else { @@ -455,7 +457,7 @@ void AttsContinueWriteReq(dmConnId_t connId, uint16_t handle, uint8_t status) p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_RSP); - L2cDataReq(L2C_CID_ATT, pCcb->handle, ATT_WRITE_RSP_LEN, pBuf); + attL2cDataReq(pCcb, ATT_BEARER_SLOT_ID, ATT_WRITE_RSP_LEN, pBuf); } } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c index 6b826393469..f25bd35d8ef 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c @@ -1,26 +1,29 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Stack configuration. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Stack configuration. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" +#include "wsf_assert.h" #include "cfg_stack.h" #include "hci_api.h" #include "dm_api.h" @@ -62,28 +65,46 @@ l2cCfg_t *pL2cCfg = (l2cCfg_t *) &l2cCfg; ATT **************************************************************************************************/ -#if MBED_CONF_CORDIO_DESIRED_ATT_MTU < ATT_DEFAULT_MTU || MBED_CONF_CORDIO_DESIRED_ATT_MTU > ATT_MAX_MTU -#error "CORDIO_CFG_DESIRED_ATT_MTU value is outside valid range" -#endif - /* Configuration structure */ -attCfg_t attCfg = +const attCfg_t attCfg = { - 15, /* ATT server service discovery connection idle timeout in seconds */ - MBED_CONF_CORDIO_DESIRED_ATT_MTU, /* desired ATT MTU */ - ATT_MAX_TRANS_TIMEOUT, /* transaction timeout in seconds */ - MBED_CONF_CORDIO_MAX_PREPARED_WRITES /* number of queued prepare writes supported by server */ + 15, /* ATT server service discovery connection idle timeout in seconds */ + ATT_DEFAULT_MTU, /* desired ATT MTU */ + ATT_MAX_TRANS_TIMEOUT, /* transcation timeout in seconds */ + 4 /* number of queued prepare writes supported by server */ }; /* Configuration pointer */ attCfg_t *pAttCfg = (attCfg_t *) &attCfg; +/************************************************************************************************** + EATT +**************************************************************************************************/ + +/* Configuration structure */ +const eattCfg_t eattCfg = +{ + 64, /* MTU */ + 64, /* MPS */ + FALSE, /* Open EATT channels automatically on connect */ + FALSE, /* Authorization required */ + DM_SEC_LEVEL_NONE, /* Security level required */ + 0, /* Number of enhanced l2cap channels per connection */ + NULL /* Channel priority table */ +}; + +/* Configuration pointer */ +eattCfg_t *pEattCfg = (eattCfg_t *) &eattCfg; + +/* EATT_CONN_CHAN_MAX cannot be greater than L2C_COC_CHAN_MAX */ +WSF_CT_ASSERT(EATT_CONN_CHAN_MAX <= L2C_COC_CHAN_MAX); + /************************************************************************************************** SMP **************************************************************************************************/ /* Configuration structure */ -smpCfg_t smpCfg = +const smpCfg_t smpCfg = { 500, /* 'Repeated attempts' timeout in msec */ SMP_IO_NO_IN_NO_OUT, /* I/O Capability */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.h index 319a40d6bab..5612481547c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Stack configuration. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Stack configuration. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef CFG_STACK_H @@ -35,9 +37,9 @@ extern "C" { **************************************************************************************************/ /*! \brief Stack release version label */ -#define STACK_VERSION ((const char *)"r19.02\n") +#define STACK_VERSION ((const char *)"Packetcraft Host v5.2\n") /*! \brief Stack release version number */ -#define STACK_VER_NUM 0x1302 /* Default value. Auto-generated by builder. */ +#define STACK_VER_NUM 1366 /************************************************************************************************** HCI @@ -81,19 +83,43 @@ extern "C" { /*! \brief Maximum number of periodic advertising synchronizations */ #ifndef DM_SYNC_MAX -#define DM_SYNC_MAX 1 +#define DM_SYNC_MAX 3 #endif /*! \brief Number of supported advertising sets: must be set to 1 for legacy advertising */ #ifndef DM_NUM_ADV_SETS -#define DM_NUM_ADV_SETS 3 +#define DM_NUM_ADV_SETS 1 #endif /*! \brief Number of scanner and initiator PHYs (LE 1M, LE 2M and LE Coded): must be set to 1 for legacy scanner and initiator */ #ifndef DM_NUM_PHYS -#define DM_NUM_PHYS 3 +#define DM_NUM_PHYS 1 +#endif + +/*! \brief Maximum number of connected isochronous groups */ +#ifndef DM_CIG_MAX +#define DM_CIG_MAX 2 +#endif + +/*! \brief Maximum number of connected isochronous streams, it is shared by CIGs */ +#ifndef DM_CIS_MAX +#define DM_CIS_MAX 6 #endif + +/*! \brief Maximum number of broadcast isochronous groups */ +#ifndef DM_BIG_MAX +#define DM_BIG_MAX 2 +#endif + +/*! \brief Maximum number of broadcast isochronous streams, it is shared by BIGs */ +#ifndef DM_BIS_MAX +#define DM_BIS_MAX 6 +#endif + +/*! \brief Maximum number of isochronous data paths, it is shared by CISes and BISes */ +#define DM_ISO_DATA_PATH_MAX (DM_CIS_MAX + DM_BIS_MAX) + /**@}*/ /************************************************************************************************** @@ -132,6 +158,12 @@ extern "C" { #ifndef ATT_NUM_SIMUL_NTF #define ATT_NUM_SIMUL_NTF 1 #endif + +/* Maximum number of EATT channels per DM connection */ +#ifndef EATT_CONN_CHAN_MAX +#define EATT_CONN_CHAN_MAX 2 +#endif + /**@}*/ /************************************************************************************************** diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c index 7ca30c6721b..b3431909a9f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager advertising module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager advertising module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -153,14 +155,14 @@ void DmAdvSetData(uint8_t advHandle, uint8_t op, uint8_t location, uint8_t len, WSF_ASSERT((location == DM_DATA_LOC_SCAN) || (location == DM_DATA_LOC_ADV)); WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); - if ((pMsg = WsfMsgAlloc(sizeof(dmAdvApiSetData_t) + len)) != NULL) + if ((pMsg = WsfMsgAlloc(sizeof(dmAdvApiSetData_t))) != NULL) { pMsg->hdr.event = DM_ADV_MSG_API_SET_DATA; pMsg->advHandle = advHandle; pMsg->op = op; pMsg->location = location; pMsg->len = len; - memcpy(pMsg->pData, pData, len); + pMsg->pData = pData; WsfMsgSend(dmCb.handlerId, pMsg); } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h index 22696a5c63d..7fca43289a6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM advertising module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM advertising module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_ADV_H @@ -78,6 +80,9 @@ enum DM_ADV_PER_STATE_STOPPING }; +/* Uninitialized HCI handle */ +#define DM_ADV_HCI_HANDLE_NONE 0xFF + /************************************************************************************************** Data Types **************************************************************************************************/ @@ -101,7 +106,7 @@ typedef struct uint8_t op; uint8_t location; uint8_t len; - uint8_t pData[]; + uint8_t *pData; } dmAdvApiSetData_t; /* Data structure for DM_ADV_MSG_API_START */ @@ -151,7 +156,7 @@ typedef struct uint8_t advHandle; uint8_t op; uint8_t len; - uint8_t pData[]; + uint8_t *pData; } dmAdvPerApiSetData_t; /* Data structure for DM_ADV_PER_MSG_API_START */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c index 9f3b36c1144..635daf02f71 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager extended advertising module. + * \file + * + * \brief Device manager extended advertising module. + * + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -74,6 +76,7 @@ typedef struct uint8_t secAdvPhy; /*!< Secondary Advertising PHY. */ bool_t scanReqNotifEna; /*!< Scan request notification enable. */ uint8_t fragPref; /*!< Fragment preference for advertising data. */ + uint8_t advSid; /*!< Advertising Sid. */ bool_t advDataSet; /*!< TRUE if extended adv data has been set. */ bool_t scanDataSet; /*!< TRUE if extended scan data has been set. */ dmConnId_t connId; /*!< Connection identifier (used by directed advertising). */ @@ -170,6 +173,7 @@ static void dmExtAdvCbInit(uint8_t advHandle) dmExtAdvCb[advHandle].secAdvPhy = HCI_ADV_PHY_LE_1M; dmExtAdvCb[advHandle].scanReqNotifEna = FALSE; dmExtAdvCb[advHandle].fragPref = HCI_ADV_DATA_FRAG_PREF_FRAG; + dmExtAdvCb[advHandle].advSid = 0; dmExtAdvCb[advHandle].connId = DM_CONN_ID_NONE; } @@ -484,7 +488,7 @@ static void dmAdvConfig(uint8_t advHandle, uint8_t advType, uint8_t peerAddrType extAdvParam.pPeerAddr = pPeerAddr; extAdvParam.advFiltPolicy = dmCb.advFiltPolicy[advHandle]; extAdvParam.advTxPwr = dmExtAdvCb[advHandle].advTxPwr; - extAdvParam.advSetId = advHandle; + extAdvParam.advSID = dmExtAdvCb[advHandle].advSid; extAdvParam.scanReqNotifEna = dmExtAdvCb[advHandle].scanReqNotifEna; /* if event type doesn't support advertising data */ @@ -1440,42 +1444,47 @@ void dmExtAdvReset(void) /*************************************************************************************************/ void dmPerAdvHciHandler(hciEvt_t *pEvent) { - dmEvt_t dmMsg; - - memcpy(&dmMsg, &pEvent->hdr, sizeof(wsfMsgHdr_t)); - - if (dmMsg.hdr.event == HCI_LE_PER_ADV_ENABLE_CMD_CMPL_CBACK_EVT) + if (pEvent->hdr.event == HCI_LE_PER_ADV_ENABLE_CMD_CMPL_CBACK_EVT) { uint8_t advHandle = dmPerAdvCmdCmplPending(); - WSF_ASSERT(advHandle < DM_NUM_ADV_SETS) - switch (dmPerAdvCb[advHandle].advState) + /* if pending periodic advertising enable command complete */ + if (advHandle < DM_NUM_ADV_SETS) { - case DM_ADV_PER_STATE_STARTING: - dmMsg.perAdvSetStart.advHandle = advHandle; - dmMsg.hdr.event = DM_PER_ADV_SET_START_IND; - dmPerAdvCb[advHandle].advState = (dmMsg.hdr.status == HCI_SUCCESS) ? \ - DM_ADV_PER_STATE_ADVERTISING : DM_ADV_PER_STATE_IDLE; - - /* call client callback */ - (*dmCb.cback)(&dmMsg); - break; + dmEvt_t dmMsg; - case DM_ADV_PER_STATE_STOPPING: - dmMsg.perAdvSetStop.advHandle = advHandle; - dmMsg.hdr.event = DM_PER_ADV_SET_STOP_IND; - /* coverity[overrun-local] */ - dmPerAdvCb[advHandle].advState = (dmMsg.hdr.status == HCI_SUCCESS) ? \ - DM_ADV_PER_STATE_IDLE : DM_ADV_PER_STATE_ADVERTISING; + /* copy over event header */ + memcpy(&dmMsg, &pEvent->hdr, sizeof(wsfMsgHdr_t)); - /* call client callback */ - (*dmCb.cback)(&dmMsg); - break; + switch (dmPerAdvCb[advHandle].advState) + { + case DM_ADV_PER_STATE_STARTING: + dmMsg.perAdvSetStart.advHandle = advHandle; + dmMsg.hdr.event = DM_PER_ADV_SET_START_IND; + dmPerAdvCb[advHandle].advState = (dmMsg.hdr.status == HCI_SUCCESS) ? \ + DM_ADV_PER_STATE_ADVERTISING : DM_ADV_PER_STATE_IDLE; + /* call client callback */ + (*dmCb.cback)(&dmMsg); + break; - default: - /* Should not happen */ - WSF_ASSERT(0); - break; + case DM_ADV_PER_STATE_STOPPING: + dmMsg.perAdvSetStop.advHandle = advHandle; + dmMsg.hdr.event = DM_PER_ADV_SET_STOP_IND; + dmPerAdvCb[advHandle].advState = (dmMsg.hdr.status == HCI_SUCCESS) ? \ + DM_ADV_PER_STATE_IDLE : DM_ADV_PER_STATE_ADVERTISING; + /* call client callback */ + (*dmCb.cback)(&dmMsg); + break; + + default: + /* Should not happen */ + WSF_ASSERT(0); + break; + } + } + else + { + DM_TRACE_WARN0("dmPerAdvHciHandler ignored due to no pending enable command complete"); } } } @@ -1660,13 +1669,13 @@ void DmPerAdvSetData(uint8_t advHandle, uint8_t op, uint8_t len, uint8_t *pData) WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); WSF_ASSERT(len <= HCI_PER_ADV_DATA_LEN); - if ((pMsg = WsfMsgAlloc(sizeof(dmAdvPerApiSetData_t) + len)) != NULL) + if ((pMsg = WsfMsgAlloc(sizeof(dmAdvPerApiSetData_t))) != NULL) { pMsg->hdr.event = DM_ADV_PER_MSG_API_SET_DATA; pMsg->advHandle = advHandle; pMsg->op = op; pMsg->len = len; - memcpy(pMsg->pData, pData, len); + pMsg->pData = pData; WsfMsgSend(dmCb.handlerId, pMsg); } } @@ -1840,6 +1849,25 @@ void DmAdvSetFragPref(uint8_t advHandle, uint8_t fragPref) WsfTaskUnlock(); } +/*************************************************************************************************/ +/*! + * \brief Set advertising SID for the given advertising handle. + * + * \param advHandle Advertising handle. + * \param advSid Advertsing SID. + * + * \return None. + */ +/*************************************************************************************************/ +void DmAdvSetSid(uint8_t advHandle, uint8_t advSid) +{ + WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); + + WsfTaskLock(); + dmExtAdvCb[advHandle].advSid = advSid; + WsfTaskUnlock(); +} + /*************************************************************************************************/ /*! * \brief Set the minimum and maximum advertising intervals for periodic advertising. @@ -1882,6 +1910,25 @@ void DmPerAdvIncTxPwr(uint8_t advHandle, bool_t incTxPwr) WsfTaskUnlock(); } +/*************************************************************************************************/ +/*! + * \brief Get status of periodic advertising handle. + * + * \param advHandle Advertising handle. + * + * \return TRUE if periodic advertising is running on that handle. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t DmPerAdvEnabled(uint8_t advHandle) +{ + if (advHandle < DM_NUM_ADV_SETS) + { + return (dmPerAdvCb[advHandle].advState == DM_ADV_PER_STATE_ADVERTISING); + } + + return FALSE; +} + /*************************************************************************************************/ /*! * \brief Get the maximum advertising data length supported by Controller for a given advertising @@ -1923,6 +1970,8 @@ void DmExtAdvInit(void) /* initialize HCI VS AE module */ HciVsAeInit(0); + HciSetLeSupFeat((HCI_LE_SUP_FEAT_LE_EXT_ADV | HCI_LE_SUP_FEAT_LE_PER_ADV), TRUE); + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_leg.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_leg.c index f71bcb79215..e8329068997 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_leg.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_leg.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager advertising module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager advertising module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_master.c new file mode 100644 index 00000000000..2c6ba3ee499 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_master.c @@ -0,0 +1,883 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Broadcast Isochronous Stream (BIS) management for master. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "dm_api.h" +#include "dm_main.h" +#include "dm_scan.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! BIS event handler messages for state machine */ +enum +{ + /* messages from API */ + DM_BIS_MSG_API_BIG_SYNC_START = DM_MSG_START(DM_ID_BIS_SYNC), /*!< Start BIG Sync */ + DM_BIS_MSG_API_BIG_SYNC_STOP, /*!< Stop BIG Sync */ + + /* messages from HCI */ + DM_BIS_MSG_HCI_LE_BIG_SYNC_EST_FAIL, /*!< HCI LE BIG Sync Establishment Failed Event */ + DM_BIS_MSG_HCI_LE_BIG_SYNC_EST, /*!< HCI LE BIG Sync Established Event */ + DM_BIS_MSG_HCI_LE_BIG_SYNC_LOST, /*!< HCI LE BIG Sync Lost Event */ + DM_BIS_MSG_HCI_LE_BIG_TERM_SYNC_CMPL /*!< HCI LE BIG Terminate Sync Complete Event */ +}; + +/*! BIS tate machine states */ +enum +{ + DM_BIS_SM_ST_IDLE, /*!< Idle State */ + DM_BIS_SM_ST_BIG_SYNCING, /*!< BIG Synchronizing State */ + DM_BIS_SM_ST_BIG_SYNCED, /*!< BIG Synced State */ + DM_BIS_SM_ST_BIG_DESYNCING, /*!< BIG Desynchronizing State */ + + DM_BIS_SM_NUM_STATES +}; + +/*! BIS state machine actions */ +enum +{ + DM_BIS_SM_ACT_NONE, /*!< No Action */ + DM_BIS_SM_ACT_BIG_SYNC_START, /*!< Process Start BG Sync */ + DM_BIS_SM_ACT_BIG_SYNC_STOP, /*!< Process Stop BIG Sync */ + DM_BIS_SM_ACT_BIG_SYNC_CANCEL_START, /*!< Process Cancel Start BIG Sync */ + DM_BIS_SM_ACT_BIG_SYNC_EST, /*!< Process BIG Sync Established */ + DM_BIS_SM_ACT_BIG_SYNC_EST_FAILED, /*!< Process BIG Sync Establishment Failed */ + DM_BIS_SM_ACT_BIG_SYNC_LOST, /*!< Process BIG Sync Lost */ + DM_BIS_SM_ACT_BIG_SYNC_STOPPED /*!< Process BIG Terminate Sync Complete */ +}; + +/*! Column position of next state */ +#define DM_BIS_NEXT_STATE 0 + +/*! Column position of action */ +#define DM_BIS_ACTION 1 + +/*! Number of columns in the state machine state tables */ +#define DM_BIS_NUM_COLS 2 + +/*! Number of messages */ +#define DM_BIS_NUM_MSGS (DM_BIS_MSG_HCI_LE_BIG_TERM_SYNC_CMPL - DM_BIS_MSG_API_BIG_SYNC_START + 1) + +/*! Translate HCI event to state machine message */ +#define DM_BIS_HCI_EVT_2_MSG(evt) (DM_BIS_MSG_HCI_LE_BIG_SYNC_LOST - HCI_LE_BIG_SYNC_LOST_CBACK_EVT + (evt)) + +/* Uninitialized HCI handle */ +#define DM_BIS_HCI_HANDLE_NONE 0xFFFF + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/* Data structure for DM_BIS_MSG_API_BIG_SYNC_START */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure. */ + uint16_t syncHandle; /*!< \brief Periodic advertising train handle. */ + uint8_t mse; /*!< \brief Maximum number of subevents. */ + uint16_t bigSyncTimeout; /*!< \brief Synchronization timeout for the BIS, in the units of 10ms. */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + uint8_t bis[DM_BIS_MAX]; /*!< \brief List of indices of BISes (in ascending order). */ +} dmBisApiBigSyncStart_t; + +/* Union of all DM BIS state machine messages */ +typedef union +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure. */ + dmBisApiBigSyncStart_t apiBigSyncStart; /*!< \brief API BIG sync start message. */ + HciLeBigTermSyncCmplEvt_t bigTermSyncCmpl; /*!< \brief LE BIG terminate sync complete. */ + HciLeBigSyncEstEvt_t bigSyncEst; /*!< \brief LE BIG sync established. */ + HciLeBigSyncLostEvt_t bigSyncLost; /*!< \brief LE BIG sync lost. */ + HciLeBigInfoAdvRptEvt_t bigInfoAdvRpt; /*!< \brief LE BIG info advertising report. */ +} dmBisMsg_t; + +/* Control block for BIG sync */ +typedef struct +{ + uint8_t state; /*!< \brief BIG state. */ + uint16_t syncHandle; /*!< \brief Periodic advertising train handle. */ + uint8_t secLevel; /*!< \brief Security level. */ + bool_t encrypt; /*!< \brief Unencrypted or Encrypted. */ + bool_t authen; /*!< \brief Unauthenticated or Authenticated. */ + uint8_t bcastCode[HCI_BC_LEN]; /*!< \brief Broadcast code. */ + + /* BIS */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + uint16_t bisHandle[DM_BIS_MAX]; /*!< \brief BIS handles. */ +} dmBigSyncCb_t; + +/*! Action function */ +typedef void (*dmBisAct_t)(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmBisSmActNone(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncStart(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncStop(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncCancelStart(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncEst(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncEstFailed(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncLost(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigSyncStopped(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg); + +static void dmBisReset(void); +static void dmBisMsgHandler(wsfMsgHdr_t *pMsg); +static void dmBisHciHandler(hciEvt_t *pEvent); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! DM BIS state machine state tables */ +static const uint8_t dmBisStateTbl[DM_BIS_SM_NUM_STATES][DM_BIS_NUM_MSGS][DM_BIS_NUM_COLS] = +{ + /* Idle state */ + { + /* Event Next state Action */ + /* API_BIG_SYNC_START */ {DM_BIS_SM_ST_BIG_SYNCING, DM_BIS_SM_ACT_BIG_SYNC_START}, + /* API_BIG_SYNC_STOP */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_EST_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_EST */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_LOST */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_TERM_SYNC_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE} + }, + /* BIG Syncing state */ + { + /* Event Next state Action */ + /* API_BIG_SYNC_START */ {DM_BIS_SM_ST_BIG_SYNCING, DM_BIS_SM_ACT_NONE}, + /* API_BIG_SYNC_STOP */ {DM_BIS_SM_ST_BIG_DESYNCING, DM_BIS_SM_ACT_BIG_SYNC_CANCEL_START}, + /* HCI_LE_BIG_SYNC_EST_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_EST_FAILED}, + /* HCI_LE_BIG_SYNC_EST */ {DM_BIS_SM_ST_BIG_SYNCED, DM_BIS_SM_ACT_BIG_SYNC_EST}, + /* HCI_LE_BIG_SYNC_LOST */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_EST_FAILED}, + /* HCI_LE_BIG_TERM_SYNC_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_EST_FAILED} + }, + /* BIG Synced state */ + { + /* Event Next state Action */ + /* API_BIG_SYNC_START */ {DM_BIS_SM_ST_BIG_SYNCED, DM_BIS_SM_ACT_NONE}, + /* API_BIG_SYNC_STOP */ {DM_BIS_SM_ST_BIG_DESYNCING, DM_BIS_SM_ACT_BIG_SYNC_STOP}, + /* HCI_LE_BIG_SYNC_EST_FAIL */ {DM_BIS_SM_ST_BIG_SYNCED, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_EST */ {DM_BIS_SM_ST_BIG_SYNCED, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_LOST */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_LOST}, + /* HCI_LE_BIG_TERM_SYNC_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_STOPPED} + }, + /* BIG Desyncing state */ + { + /* Event Next state Action */ + /* API_BIG_SYNC_START */ {DM_BIS_SM_ST_BIG_DESYNCING, DM_BIS_SM_ACT_NONE}, + /* API_BIG_SYNC_STOP */ {DM_BIS_SM_ST_BIG_DESYNCING, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_BIG_SYNC_EST_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_EST_FAILED}, + /* HCI_LE_BIG_SYNC_EST */ {DM_BIS_SM_ST_BIG_DESYNCING, DM_BIS_SM_ACT_BIG_SYNC_STOP}, + /* HCI_LE_BIG_SYNC_LOST */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_LOST}, + /* HCI_LE_BIG_TERM_SYNC_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_SYNC_STOPPED} + } +}; + +/*! DM BIS action function table */ +static const dmBisAct_t dmBisAct[] = +{ + dmBisSmActNone, + dmBisSmActBigSyncStart, + dmBisSmActBigSyncStop, + dmBisSmActBigSyncCancelStart, + dmBisSmActBigSyncEst, + dmBisSmActBigSyncEstFailed, + dmBisSmActBigSyncLost, + dmBisSmActBigSyncStopped +}; + +/*! DM BIS component function interface */ +static const dmFcnIf_t dmBisFcnIf = +{ + dmBisReset, + dmBisHciHandler, + dmBisMsgHandler +}; + +/*!< DM BIG sync control block. */ +static dmBigSyncCb_t dmBigSyncCb[DM_BIG_MAX]; + +/*************************************************************************************************/ +/*! + * \brief Initialize the BIG sync CB for a given handle. + * + * \param pBigSyncCb BIG sync CB. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBigSyncCbInit(dmBigSyncCb_t *pBigSyncCb) +{ + /* set BIG sync default values */ + pBigSyncCb->state = DM_BIS_SM_ST_IDLE; + pBigSyncCb->syncHandle = DM_SYNC_HCI_HANDLE_NONE; + pBigSyncCb->encrypt = FALSE; + memset(pBigSyncCb->bcastCode, 0x000, HCI_BC_LEN); + + pBigSyncCb->numBis = 0; + for (uint8_t i = 0; i < DM_BIS_MAX; i++) + { + pBigSyncCb->bisHandle[i] = DM_BIS_HCI_HANDLE_NONE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Get the BIG sync CB for a given handle. + * + * \param bigHandle BIG handle. + * + * \return Pointer to BIG sync control block if BIG handle valid. NULL, otherwise. + */ +/*************************************************************************************************/ +static dmBigSyncCb_t *dmBigSyncCbByHandle(uint8_t bigHandle) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + if (bigHandle < DM_BIG_MAX) + { + return &dmBigSyncCb[bigHandle]; + } + + DM_TRACE_WARN1("dmBigSyncCbByHandle: out of range bigHandle = %d", bigHandle); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the sync handle is associated with another BIG sync. + * + * \param syncHandle Sync handle. + * + * \return TRUE if sync handle is associated with another BIG sync. FALSE, otherwise. + */ +/*************************************************************************************************/ +static bool_t dmBigSyncUsed(uint16_t syncHandle) +{ + for (uint8_t i = 0; i < DM_BIG_MAX; i++) + { + dmBigSyncCb_t *pBigSyncCb = &dmBigSyncCb[i]; + + if ((pBigSyncCb->state != DM_BIS_SM_ST_IDLE) && (pBigSyncCb->syncHandle == syncHandle)) + { + return TRUE; + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available BISes. + * + * \return Number of available BISes. + */ +/*************************************************************************************************/ +static uint8_t dmBigSyncGetNumAvailBis(void) +{ + uint8_t cnt = 0; + + for (uint8_t i = 0; i < DM_BIG_MAX; i++) + { + dmBigSyncCb_t *pBigSyncCb = &dmBigSyncCb[i]; + + if (pBigSyncCb->state != DM_BIS_SM_ST_IDLE) + { + cnt += pBigSyncCb->numBis; + } + } + + if (cnt >= DM_BIS_MAX) + { + return 0; + } + + return (DM_BIS_MAX - cnt); +} + +/*************************************************************************************************/ +/*! + * \brief Empty action. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActNone(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Start BIG sync for the given BIG. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncStart(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + dmBisApiBigSyncStart_t *pBigSyncStart = &pMsg->apiBigSyncStart; + uint8_t bigHandle = (uint8_t) pMsg->hdr.param; + uint8_t status = HCI_SUCCESS; + + if (DmSyncEnabled(pBigSyncStart->syncHandle)) + { + if (!dmBigSyncUsed(pBigSyncStart->syncHandle)) + { + if ((pBigSyncStart->numBis > 0) && (pBigSyncStart->numBis <= DM_BIS_MAX)) + { + if (dmBigSyncCb[bigHandle].encrypt == DmSyncEncrypted(pBigSyncStart->syncHandle)) + { + if (pBigSyncStart->numBis > dmBigSyncGetNumAvailBis()) + { + DM_TRACE_WARN0("dmBisSmActBigSyncStart: insufficient BISes"); + status = HCI_ERR_REJ_RESOURCES; + } + } + else + { + DM_TRACE_WARN0("dmBisSmActBigSyncStart: encryption mode mismatch"); + status = HCI_ERR_ENCRYPT_MODE; + } + } + else + { + DM_TRACE_WARN2("dmBisSmActBigSyncStart: invalid value for numBis = %u, validRange = 1..%u", + pBigSyncStart->numBis, DM_BIS_MAX); + status = HCI_ERR_UNSUP_FEAT; + } + } + else + { + DM_TRACE_WARN0("dmBisSmActBigSyncStart: periodic advertising train is associated with another BIG"); + status = HCI_ERR_UNKNOWN_ADV_ID; + } + } + else + { + DM_TRACE_WARN1("dmBisSmActBigSyncStart: syncHandle = %u not found", pBigSyncStart->syncHandle); + status = HCI_ERR_UNKNOWN_ADV_ID; + } + + if (status == HCI_SUCCESS) + { + HciBigCreateSync_t createSync; + + /* build BIG parameters */ + createSync.bigHandle = bigHandle; + createSync.syncHandle = pBigSyncStart->syncHandle; + createSync.encrypt = dmBigSyncCb[bigHandle].encrypt; + memcpy(createSync.bcstCode, dmBigSyncCb[bigHandle].bcastCode, HCI_BC_LEN); + createSync.mse = pBigSyncStart->mse; + createSync.bigSyncTimeout = pBigSyncStart->bigSyncTimeout; + createSync.numBis = pBigSyncStart->numBis; + memcpy(createSync.bis, pBigSyncStart->bis, pBigSyncStart->numBis); + + /* create BIG sync */ + HciLeBigCreateSyncCmd(&createSync); + + /* update BIG sync CB */ + dmBigSyncCb[bigHandle].syncHandle = pBigSyncStart->syncHandle; + dmBigSyncCb[bigHandle].numBis = pBigSyncStart->numBis; + } + else + { + pMsg->hdr.status = status; + + /* notify app about failure */ + dmBisSmActBigSyncEstFailed(pBigSyncCb, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Stop BIG sync for the given BIG. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncStop(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + HciLeBigTerminateSync((uint8_t) pMsg->hdr.param); +} + +/*************************************************************************************************/ +/*! + * \brief Cancel creation of a BIG sync while it's pending. + * + * \param pBigSyncCb Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncCancelStart(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + HciLeBigTerminateSync((uint8_t) pMsg->hdr.param); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a BIG sync established event from HCI. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncEst(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + /* save connection handles of BISes */ + pBigSyncCb->numBis = WSF_MIN(pMsg->bigSyncEst.numBis, DM_BIS_MAX); + for (uint8_t i = 0; i < pBigSyncCb->numBis; i++) + { + pBigSyncCb->bisHandle[i] = pMsg->bigSyncEst.bisHandle[i]; + } + + pMsg->hdr.event = DM_BIG_SYNC_EST_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a BIG sync established failure event from HCI. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncEstFailed(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + /* reset BIG sync cb */ + dmBigSyncCbInit(pBigSyncCb); + + pMsg->hdr.event = DM_BIG_SYNC_EST_FAIL_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a BIG sync lost event from HCI. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncLost(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + /* reset BIG sync cb */ + dmBigSyncCbInit(pBigSyncCb); + + pMsg->hdr.event = DM_BIG_SYNC_LOST_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a BIG terminate sync complete event from HCI. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmBisSmActBigSyncStopped(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + /* reset BIG sync cb */ + dmBigSyncCbInit(pBigSyncCb); + + pMsg->hdr.event = DM_BIG_SYNC_STOP_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Execute the DM BIS state machine. + * + * \param pBigSyncCb BIG Sync control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisSmExecute(dmBigSyncCb_t *pBigSyncCb, dmBisMsg_t *pMsg) +{ + uint8_t action; + uint8_t event; + + DM_TRACE_INFO2("dmBisSmExecute event=%d state=%d", pMsg->hdr.event, pBigSyncCb->state); + + /* get the event */ + event = DM_MSG_MASK(pMsg->hdr.event); + + /* get action */ + action = dmBisStateTbl[pBigSyncCb->state][event][DM_BIS_ACTION]; + + /* set next state */ + pBigSyncCb->state = dmBisStateTbl[pBigSyncCb->state][event][DM_BIS_NEXT_STATE]; + + /* execute action function */ + (*dmBisAct[action])(pBigSyncCb, pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Reset the BIS module. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisReset(void) +{ + dmBigSyncCb_t *pBigSyncCb = dmBigSyncCb; + HciLeBigSyncLostEvt_t bigSyncLost; + + /* generate HCI BIG sync lost event */ + bigSyncLost.hdr.event = HCI_LE_BIG_SYNC_LOST_CBACK_EVT; + bigSyncLost.hdr.status = HCI_SUCCESS; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigSyncCb++) + { + if (pBigSyncCb->state != DM_BIS_SM_ST_IDLE) + { + /* set BIG sync handle */ + bigSyncLost.hdr.param = bigSyncLost.bigHandle = i; + + /* handle the event */ + dmBisHciHandler((hciEvt_t *) &bigSyncLost); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM BIS HCI event handler. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisHciHandler(hciEvt_t *pEvent) +{ + dmBigSyncCb_t *pBigSyncCb; + + /* handle special case for BIGInfo advertising report event */ + if (pEvent->hdr.event == HCI_LE_BIG_INFO_ADV_REPORT_CBACK_EVT) + { + /* if periodic advertising sync has been established */ + if (DmSyncEnabled(pEvent->hdr.param)) + { + /* store sync info */ + DmSyncSetEncrypt(pEvent->hdr.param, pEvent->leBigInfoAdvRpt.encrypt); + + pEvent->hdr.event = DM_BIG_INFO_ADV_REPORT_IND; + (*dmCb.cback)((dmEvt_t *) pEvent); + } + + return; + } + + pBigSyncCb = dmBigSyncCbByHandle((uint8_t) pEvent->hdr.param); + + /* handle special cases for BIG sync established event */ + if (pEvent->hdr.event == HCI_LE_BIG_SYNC_EST_CBACK_EVT) + { + /* translate HCI event to state machine event */ + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_BIS_MSG_HCI_LE_BIG_SYNC_EST; + } + else + { + pEvent->hdr.event = DM_BIS_MSG_HCI_LE_BIG_SYNC_EST_FAIL; + } + } + else /* HCI_LE_BIG_SYNC_LOST_CBACK_EVT */ + { + /* translate HCI event to state machine message */ + pEvent->hdr.event = DM_BIS_HCI_EVT_2_MSG(pEvent->hdr.event); + } + + /* if scb found */ + if (pBigSyncCb != NULL) + { + /* execute state machine */ + dmBisSmExecute(pBigSyncCb, (dmBisMsg_t *) pEvent); + } +} + +/*************************************************************************************************/ +/*! + * \brief DM BIG event handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmBigSyncCb_t *pBigSyncCb; + + /* look up CB from BIG handle */ + if ((pBigSyncCb = dmBigSyncCbByHandle((uint8_t) pMsg->param)) != NULL) + { + /* execute state machine */ + dmBisSmExecute(pBigSyncCb, (dmBisMsg_t *) pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Synchronize to a Broadcast Isochronous Group (BIG) described in the periodic + * advertising train specified by the sync handle. + * + * \param bigHandle BIG handle. + * \param syncHandle Periodic advertising train handle. + * \param mse Maximum number of subevents. + * \param bigSyncTimeout Synchronization timeout for the BIS, in the units of 10ms. + * \param numBis Total number of BISes in the BIG. + * \param pBis List of indices of BISes (in ascending order). + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncStart(uint8_t bigHandle, uint16_t syncHandle, uint8_t mse, uint16_t bigSyncTimeout, + uint8_t numBis, uint8_t *pBis) +{ + dmBisApiBigSyncStart_t *pMsg; + + WSF_ASSERT(bigHandle < DM_BIG_MAX); + WSF_ASSERT((numBis > 0 ) && (numBis <= DM_BIS_MAX)); + + if ((pMsg = WsfMsgAlloc(sizeof(dmBisApiBigSyncStart_t))) != NULL) + { + pMsg->hdr.param = bigHandle; + pMsg->hdr.event = DM_BIS_MSG_API_BIG_SYNC_START; + pMsg->syncHandle = syncHandle; + pMsg->mse = mse; + pMsg->bigSyncTimeout = bigSyncTimeout; + pMsg->numBis = numBis; + memcpy(pMsg->bis, pBis, numBis); + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Stop synchronizing or cancel the process of synchronizing to the Broadcast Isochronous + * Group (BIG) identified by the handle. + * + * \note The command also terminates the reception of BISes in the BIG specified in \ref + * DmBigSyncStart, destroys the associated connection handles of the BISes in the BIG + * and removes the data paths for all BISes in the BIG. + * + * \param bigHandle BIG handle. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncStop(uint8_t bigHandle) +{ + wsfMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(wsfMsgHdr_t))) != NULL) + { + pMsg->param = bigHandle; + pMsg->event = DM_BIS_MSG_API_BIG_SYNC_STOP; + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the BIS sync is in use. + * + * \param handle BIS connection handle. + * + * \return TRUE if the BIS sync is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmBisSyncInUse(uint16_t handle) +{ + dmBigSyncCb_t *pBigSyncCb = dmBigSyncCb; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigSyncCb++) + { + if (pBigSyncCb->state == DM_BIS_SM_ST_IDLE) + { + continue; + } + + for (uint8_t j = 0; j < pBigSyncCb->numBis; j++) + { + if (pBigSyncCb->bisHandle[j] == handle) + { + return TRUE; + } + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Set the Broadcast Code for the given Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param encrypt FALSE (Unencrypted) or TRUE (Encrypted). + * \param authen FALSE (Unauthenticated) or TRUE (Authenticated). + * \param pBcastCode Broadcast code. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncSetBcastCode(uint8_t bigHandle, bool_t encrypt, bool_t authen, uint8_t *pBcastCode) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + WsfTaskLock(); + + if (encrypt) + { + dmBigSyncCb[bigHandle].encrypt = TRUE; + dmBigSyncCb[bigHandle].authen = authen; + memcpy(dmBigSyncCb[bigHandle].bcastCode, pBcastCode, HCI_BC_LEN); + } + else + { + dmBigSyncCb[bigHandle].encrypt = FALSE; + dmBigSyncCb[bigHandle].authen = FALSE; + memset(dmBigSyncCb[bigHandle].bcastCode, 0x000, HCI_BC_LEN); + } + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG). + * + * \param bigHandle BIG handle. + * \param secLevel Security level. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSyncSetSecLevel(uint8_t bigHandle, uint8_t secLevel) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + WSF_ASSERT(secLevel <= DM_SEC_LEVEL_BCAST_AUTH); + + WsfTaskLock(); + + dmBigSyncCb[bigHandle].secLevel = secLevel; + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Get the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG) connection handle. + * + * \param handle BIS connection handle. + * + * \return Security level. + */ +/*************************************************************************************************/ +uint8_t DmBigSyncGetSecLevel(uint16_t handle) +{ + dmBigSyncCb_t *pBigSyncCb = dmBigSyncCb; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigSyncCb++) + { + if (pBigSyncCb->state == DM_BIS_SM_ST_IDLE) + { + continue; + } + + for (uint8_t j = 0; j < pBigSyncCb->numBis; j++) + { + if (pBigSyncCb->bisHandle[j] == handle) + { + return pBigSyncCb->secLevel; + } + } + } + + return DM_SEC_LEVEL_BCAST_NONE; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM BIS manager for operation as master. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBisMasterInit(void) +{ + WsfTaskLock(); + + dmBigSyncCb_t *pBigSyncCb = dmBigSyncCb; + + dmFcnIfTbl[DM_ID_BIS_SYNC] = (dmFcnIf_t *) &dmBisFcnIf; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigSyncCb++) + { + dmBigSyncCbInit(pBigSyncCb); + } + + HciSetLeSupFeat((HCI_LE_SUP_FEAT_ISO_SYNC_RECEIVER | HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT), TRUE); + + WsfTaskUnlock(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_slave.c new file mode 100644 index 00000000000..c3fb5cfef31 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_bis_slave.c @@ -0,0 +1,905 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Broadcast Isochronous Stream (BIS) management for slave. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_os.h" +#include "dm_api.h" +#include "dm_dev.h" +#include "dm_main.h" +#include "dm_adv.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! BIS event handler messages for state machine */ +enum +{ + /* messages from API */ + DM_BIS_MSG_API_BIG_START = DM_MSG_START(DM_ID_BIS), /*!< Start BIG */ + DM_BIS_MSG_API_BIG_STOP, /*!< Stop BIG */ + + /* messages from HCI */ + DM_BIS_MSG_HCI_LE_CREATE_BIG_CMPL_FAIL, /*!< HCI LE Create BIG Complete Failed Event */ + DM_BIS_MSG_HCI_LE_CREATE_BIG_CMPL, /*!< HCI LE Create BIG Complete Event */ + DM_BIS_MSG_HCI_LE_TERM_BIG_CMPL /*!< HCI LE Terminate BIG Complete Event */ +}; + +/*! BIS state machine states */ +enum +{ + DM_BIS_SM_ST_IDLE, /*!< Idle State */ + DM_BIS_SM_ST_BIG_STARTING, /*!< BIG Starting State */ + DM_BIS_SM_ST_BIG_STARTED, /*!< BIG Started State */ + DM_BIS_SM_ST_BIG_STOPPING, /*!< BIG Stopping State */ + + DM_BIS_SM_NUM_STATES +}; + +/*! BIS state machine actions */ +enum +{ + DM_BIS_SM_ACT_NONE, /*!< No Action */ + DM_BIS_SM_ACT_BIG_START, /*!< Process Start BIG */ + DM_BIS_SM_ACT_BIG_STOP, /*!< Process Stop BIG */ + DM_BIS_SM_ACT_BIG_CANCEL_START, /*!< Process Cancel Start BIG */ + DM_BIS_SM_ACT_BIG_STARTED, /*!< Process BIG Started */ + DM_BIS_SM_ACT_BIG_START_FAILED, /*!< Process BIG Start Failed */ + DM_BIS_SM_ACT_BIG_STOPPED /*!< Process BIG Stopped */ +}; + +/*! Column position of next state */ +#define DM_BIS_NEXT_STATE 0 + +/*! Column position of action */ +#define DM_BIS_ACTION 1 + +/*! Number of columns in the state machine state tables */ +#define DM_BIS_NUM_COLS 2 + +/* Number of BIS messages */ +#define DM_BIS_NUM_MSGS (DM_BIS_MSG_HCI_LE_TERM_BIG_CMPL - DM_BIS_MSG_API_BIG_START + 1) + +/*! Translate HCI event to state machine message */ +#define DM_BIS_HCI_EVT_2_MSG(evt) (DM_BIS_MSG_HCI_LE_TERM_BIG_CMPL - HCI_LE_TERM_BIG_CMPL_CBACK_EVT + (evt)) + +/* Uninitialized HCI BIS handle */ +#define DM_BIS_HCI_HANDLE_NONE 0xFFFF + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/* Data structure for DM_BIS_MSG_API_BIG_START */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure. */ + uint8_t advHandle; /*!< \brief Used to identify the periodic advertising train. */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + uint32_t sduInterval; /*!< \brief Interval, in microseconds, of BIG SDUs. */ + uint16_t maxSdu; /*!< \brief Maximum size of SDU. */ + uint16_t mtlMs; /*!< \brief Maximum time, in milliseconds, for transmitting SDU. */ + uint8_t rtn; /*!< \brief Retransmitted number. */ +} dmBisApiBigStart_t; + +/* Data structure for DM_BIS_MSG_API_BIG_STOP */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure. */ + uint8_t reason; /*!< \brief Reason BIG is terminated. */ +} dmBisApiBigStop_t; + +/* Union of all DM BIS state machine messages */ +typedef union +{ + wsfMsgHdr_t hdr; /*!< \brief Header structure. */ + dmBisApiBigStart_t apiBigStart; /*!< \brief API BIG start message. */ + dmBisApiBigStop_t apiBigStop; /*!< \brief API BIG stop message. */ + HciLeCreateBigCmplEvt_t createBigCmpl; /*!< \brief HCI create BIG complete event. */ + HciLeTerminateBigCmplEvt_t terminateBigCmpl; /*!< \brief HCI terminate BIG complete event. */ +} dmBisMsg_t; + +/* Control block for BIG */ +typedef struct +{ + uint8_t state; /*!< \brief BIG state. */ + uint8_t advHandle; /*!< \brief Periodic advertising train associated with BIG. */ + uint8_t phyBits; /*!< \brief Transmitter PHYs of packets. */ + uint8_t packing; /*!< \brief Packing scheme. */ + uint8_t framing; /*!< \brief Format of BIS Data PDUs. */ + uint8_t secLevel; /*!< \brief Security level. */ + bool_t encrypt; /*!< \brief Unencrypted or Encrypted. */ + bool_t authen; /*!< \brief Unauthenticated or Authenticated. */ + uint8_t bcastCode[HCI_BC_LEN]; /*!< \brief Braodcast code. */ + + /* BIS */ + uint8_t numBis; /*!< \brief Total number of BISes in the BIG. */ + //uint8_t bis[DM_BIS_MAX]; /*!< \brief List of indices of BISes (in ascending order). */ + uint16_t bisHandle[DM_BIS_MAX]; /*!< \brief BIS handles. */ +} dmBigCb_t; + +/*! Action function */ +typedef void (*dmBisAct_t)(dmBigCb_t *pCcb, dmBisMsg_t *pMsg); + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmBisSmActNone(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigStart(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigStop(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigCancelStart(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigStarted(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigStartFailed(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); +static void dmBisSmActBigStopped(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg); + +static void dmBisReset(void); +static void dmBisMsgHandler(wsfMsgHdr_t *pMsg); +static void dmBisHciHandler(hciEvt_t *pEvent); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! DM BIS state machine state tables */ +static const uint8_t dmBisStateTbl[DM_BIS_SM_NUM_STATES][DM_BIS_NUM_MSGS][DM_BIS_NUM_COLS] = +{ + /* Idle state */ + { + /* Event Next state Action */ + /* API_BIG_START */ {DM_BIS_SM_ST_BIG_STARTING, DM_BIS_SM_ACT_BIG_START}, + /* API_BIG_STOP */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_CREATE_BIG_CMPL_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_CREATE_BIG_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_TERM_BIG_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_NONE} + }, + /* Starting state */ + { + /* Event Next state Action */ + /* API_BIG_START */ {DM_BIS_SM_ST_BIG_STARTING, DM_BIS_SM_ACT_NONE}, + /* API_BIG_STOP */ {DM_BIS_SM_ST_BIG_STOPPING, DM_BIS_SM_ACT_BIG_CANCEL_START}, + /* HCI_LE_CREATE_BIG_CMPL_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_START_FAILED}, + /* HCI_LE_CREATE_BIG_CMPL */ {DM_BIS_SM_ST_BIG_STARTED, DM_BIS_SM_ACT_BIG_STARTED}, + /* HCI_LE_TERM_BIG_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_START_FAILED} + }, + /* Started state */ + { + /* Event Next state Action */ + /* API_BIG_START */ {DM_BIS_SM_ST_BIG_STARTED, DM_BIS_SM_ACT_NONE}, + /* API_BIG_STOP */ {DM_BIS_SM_ST_BIG_STOPPING, DM_BIS_SM_ACT_BIG_STOP}, + /* HCI_LE_CREATE_BIG_CMPL_FAIL */ {DM_BIS_SM_ST_BIG_STARTED, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_CREATE_BIG_CMPL */ {DM_BIS_SM_ST_BIG_STARTED, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_TERM_BIG_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_STOPPED} + }, + /* Stopping state */ + { + /* Event Next state Action */ + /* API_BIG_START */ {DM_BIS_SM_ST_BIG_STOPPING, DM_BIS_SM_ACT_NONE}, + /* API_BIG_STOP */ {DM_BIS_SM_ST_BIG_STOPPING, DM_BIS_SM_ACT_NONE}, + /* HCI_LE_CREATE_BIG_CMPL_FAIL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_START_FAILED}, + /* HCI_LE_CREATE_BIG_CMPL */ {DM_BIS_SM_ST_BIG_STOPPING, DM_BIS_SM_ACT_BIG_STOP}, + /* HCI_LE_TERM_BIG_CMPL */ {DM_BIS_SM_ST_IDLE, DM_BIS_SM_ACT_BIG_STOPPED} + } + }; + +/*! DM BIS action function table */ +static const dmBisAct_t dmBisAct[] = +{ + dmBisSmActNone, + dmBisSmActBigStart, + dmBisSmActBigStop, + dmBisSmActBigCancelStart, + dmBisSmActBigStarted, + dmBisSmActBigStartFailed, + dmBisSmActBigStopped +}; + +/*! DM BIG component function interface */ +static const dmFcnIf_t dmBisFcnIf = +{ + dmBisReset, + dmBisHciHandler, + dmBisMsgHandler +}; + +/*! DM BIG control block */ +static dmBigCb_t dmBigCb[DM_BIG_MAX]; + +/*************************************************************************************************/ +/*! + * \brief Initialize the BIG CB for a given handle. + * + * \param pBigCb BIG CB. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBigCbInit(dmBigCb_t *pBigCb) +{ + /* set BIG default values */ + pBigCb->state = DM_BIS_SM_ST_IDLE; + pBigCb->advHandle = DM_ADV_HCI_HANDLE_NONE; + pBigCb->numBis = 0; + pBigCb->phyBits = HCI_TRANS_PHY_LE_1M_BIT; + pBigCb->packing = HCI_PACKING_SEQUENTIAL; + pBigCb->framing = HCI_FRAMING_UNFRAMED; + pBigCb->encrypt = FALSE; + memset(pBigCb->bcastCode, 0x000, HCI_BC_LEN); + + pBigCb->numBis = 0; + for (uint8_t i = 0; i < DM_BIS_MAX; i++) + { + pBigCb->bisHandle[i] = DM_BIS_HCI_HANDLE_NONE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Get the BIG CB for a given handle. + * + * \param bigHandle BIG handle. + * + * \return Pointer to BIG control block if BIG handle valid. NULL, otherwise. + */ +/*************************************************************************************************/ +static dmBigCb_t *dmBigCbByHandle(uint8_t bigHandle) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + if (bigHandle < DM_BIG_MAX) + { + return &dmBigCb[bigHandle]; + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the periodic advertising handle is associated with another BIG. + * + * \param advHandle Periodic advertising handle. + * + * \return TRUE if periodic advertising handle is associated with another BIG. FALSE, otherwise. + */ +/*************************************************************************************************/ +static bool_t dmBigPerAdvUsed(uint8_t advHandle) +{ + for (uint8_t i = 0; i < DM_BIG_MAX; i++) + { + dmBigCb_t *pBigCb = &dmBigCb[i]; + + if ((pBigCb->state != DM_BIS_SM_ST_IDLE) && (pBigCb->advHandle == advHandle)) + { + return TRUE; + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available BISes. + * + * \return Number of available BISes. + */ +/*************************************************************************************************/ +static uint8_t dmBigGetNumAvailBis(void) +{ + uint8_t cnt = 0; + + for (uint8_t i = 0; i < DM_BIG_MAX; i++) + { + dmBigCb_t *pBigCb = &dmBigCb[i]; + + if (pBigCb->state != DM_BIS_SM_ST_IDLE) + { + cnt += pBigCb->numBis; + } + } + + if (cnt >= DM_BIS_MAX) + { + return 0; + } + + return (DM_BIS_MAX - cnt); +} + +/*************************************************************************************************/ +/*! +* \brief Empty action. +* +* \param pBigCb CIG control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisSmActNone(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Create BIG for the given BIG. + * + * \param pBigCb CIG control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisSmActBigStart(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + dmBisApiBigStart_t *pBigStart = &pMsg->apiBigStart; + uint8_t bigHandle = (uint8_t) pMsg->hdr.param; + uint8_t status = HCI_SUCCESS; + + if (DmPerAdvEnabled(pBigStart->advHandle)) + { + if (!dmBigPerAdvUsed(pBigStart->advHandle)) + { + if ((pBigStart->numBis > 0) && (pBigStart->numBis <= DM_BIS_MAX)) + { + if (pBigStart->numBis > dmBigGetNumAvailBis()) + { + DM_TRACE_WARN0("dmBisSmActStart: insufficient BISes"); + status = HCI_ERR_REJ_RESOURCES; + } + } + else + { + DM_TRACE_WARN2("dmBisSmActStart: invalid value for numBis = %u, validRange = 1..%u", + pBigStart->numBis, DM_BIS_MAX); + status = HCI_ERR_UNSUP_FEAT; + } + } + else + { + DM_TRACE_WARN0("dmBisSmActStart: periodic advertising train is associated with another BIG"); + status = HCI_ERR_UNKNOWN_ADV_ID; + } + } + else + { + DM_TRACE_WARN0("dmBisSmActStart: advHandle does not identify a periodic advertising train"); + status = HCI_ERR_UNKNOWN_ADV_ID; + } + + if (status == HCI_SUCCESS) + { + HciCreateBig_t createBig; + + /* build BIG parameters */ + createBig.bigHandle = bigHandle; + createBig.advHandle = pBigStart->advHandle; + createBig.numBis = pBigStart->numBis; + createBig.sduInterUsec = pBigStart->sduInterval; + createBig.maxSdu = pBigStart->maxSdu; + createBig.mtlMs = pBigStart->mtlMs; + createBig.rtn = pBigStart->rtn; + createBig.phys = dmBigCb[bigHandle].phyBits; + createBig.packing = dmBigCb[bigHandle].packing; + createBig.framing = dmBigCb[bigHandle].framing; + createBig.encrypt = dmBigCb[bigHandle].encrypt; + memcpy(createBig.bcstCode, dmBigCb[bigHandle].bcastCode, HCI_BC_LEN); + + /* create BIG */ + HciLeCreateBigCmd(&createBig); + + /* update BIG CB */ + dmBigCb[bigHandle].advHandle = pBigStart->advHandle; + dmBigCb[bigHandle].numBis = pBigStart->numBis; + } + else + { + pMsg->hdr.status = status; + + /* notify app about failure */ + dmBisSmActBigStartFailed(pBigCb, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Terminate BIG for the given BIG. + * + * \param pBigCb CIG control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisSmActBigStop(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + dmBisApiBigStop_t *pBigStop = &pMsg->apiBigStop; + + HciTerminateBigCmd((uint8_t) pMsg->hdr.param, pBigStop->reason); +} + +/*************************************************************************************************/ +/*! +* \brief Cancel a create BIG. +* +* \param pCcb CIS connection control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisSmActBigCancelStart(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + dmBisApiBigStop_t *pBigStop = &pMsg->apiBigStop; + + HciTerminateBigCmd((uint8_t) pMsg->hdr.param, pBigStop->reason); +} + +/*************************************************************************************************/ +/*! +* \brief Handle a create BIG complete event from HCI. +* +* \param pBigCb CIG control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisSmActBigStarted(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + /* save connection handles of BISes */ + pBigCb->numBis = WSF_MIN(pMsg->createBigCmpl.numBis, DM_BIS_MAX); + for (uint8_t i = 0; i < pBigCb->numBis; i++) + { + pBigCb->bisHandle[i] = pMsg->createBigCmpl.bisHandle[i]; + } + + pMsg->hdr.event = DM_BIG_START_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! +* \brief Handle a create BIG failure complete event from HCI. +* +* \param pBigCb CIG control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisSmActBigStartFailed(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + /* reset BIG cb */ + dmBigCbInit(pBigCb); + + pMsg->hdr.event = DM_BIG_START_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! +* \brief Handle a terminate BIG complete event from HCI. +* +* \param pBigCb CIG control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisSmActBigStopped(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + /* reset BIG cb */ + dmBigCbInit(pBigCb); + + pMsg->hdr.event = DM_BIG_STOP_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Execute the DM BIG state machine. + * + * \param pBigCb BIG control block. + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisSmExecute(dmBigCb_t *pBigCb, dmBisMsg_t *pMsg) +{ + uint8_t action; + uint8_t event; + + DM_TRACE_INFO2("dmBisSmExecute event=%d state=%d", pMsg->hdr.event, pBigCb->state); + + /* get the event */ + event = DM_MSG_MASK(pMsg->hdr.event); + + /* get action */ + action = dmBisStateTbl[pBigCb->state][event][DM_BIS_ACTION]; + + /* set next state */ + pBigCb->state = dmBisStateTbl[pBigCb->state][event][DM_BIS_NEXT_STATE]; + + /* execute action function */ + (*dmBisAct[action])(pBigCb, pMsg); +} + +/*************************************************************************************************/ +/*! +* \brief Reset the BIS module. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisReset(void) +{ + dmBigCb_t *pBigCb = dmBigCb; + HciLeTerminateBigCmplEvt_t terminateBigCmpl; + + /* generate HCI BIG sync lost event */ + terminateBigCmpl.hdr.event = HCI_LE_TERM_BIG_CMPL_CBACK_EVT; + terminateBigCmpl.hdr.status = HCI_SUCCESS; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigCb++) + { + if (pBigCb->state != DM_BIS_SM_ST_IDLE) + { + /* set BIG sync handle */ + terminateBigCmpl.hdr.param = terminateBigCmpl.bigHandle = i; + + /* handle the event */ + dmBisHciHandler((hciEvt_t *) &terminateBigCmpl); + } + } +} + +/*************************************************************************************************/ +/*! +* \brief DM BIS HCI callback event handler. +* +* \param pEvent Pointer to HCI callback event structure. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmBisHciHandler(hciEvt_t *pEvent) +{ + dmBigCb_t *pBigCb = dmBigCbByHandle((uint8_t) pEvent->hdr.param); + + /* translate HCI event to state machine event */ + if (pEvent->hdr.event == HCI_LE_CREATE_BIG_CMPL_CBACK_EVT) + { + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_BIS_MSG_HCI_LE_CREATE_BIG_CMPL; + } + else + { + pEvent->hdr.event = DM_BIS_MSG_HCI_LE_CREATE_BIG_CMPL_FAIL; + } + } + else /* HCI_LE_TERMINATE_BIG_CMPL_CBACK_EVT */ + { + pEvent->hdr.event = DM_BIS_MSG_HCI_LE_TERM_BIG_CMPL; + } + + /* if BIG cb found */ + if (pBigCb != NULL) + { + /* execute state machine */ + dmBisSmExecute(pBigCb, (dmBisMsg_t *) pEvent); + } +} + +/*************************************************************************************************/ +/*! + * \brief DM BIS WSF message handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmBisMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmBigCb_t *pBigCb; + + /* look up CB from BIG handle */ + if ((pBigCb = dmBigCbByHandle((uint8_t) pMsg->param)) != NULL) + { + /* execute state machine */ + dmBisSmExecute(pBigCb, (dmBisMsg_t *) pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Start a Broadcast Isochronous Group (BIG) with one or more Broadcast Isochronous + * Streams (BISes). + * + * \param bigHandle BIG identifier. + * \param advHandle Used to identify the periodic advertising train. + * \param numBis; Total number of BISes in the BIG. + * \param sduInterval Interval, in microseconds, of BIG SDUs. + * \param maxSdu Maximum size of SDU. + * \param mtlMs Maximum time, in milliseconds, for transmitting SDU. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigStart(uint8_t bigHandle, uint8_t advHandle, uint8_t numBis, uint32_t sduInterval, + uint16_t maxSdu, uint16_t mtlMs, uint8_t rtn) +{ + dmBisApiBigStart_t *pMsg; + + WSF_ASSERT(bigHandle < DM_BIG_MAX); + WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); + WSF_ASSERT((numBis > 0 ) && (numBis <= DM_BIS_MAX)); + + if ((pMsg = WsfMsgAlloc(sizeof(dmBisApiBigStart_t))) != NULL) + { + pMsg->hdr.event = DM_BIS_MSG_API_BIG_START; + pMsg->hdr.param = bigHandle; + pMsg->advHandle = advHandle; + pMsg->numBis = numBis; + pMsg->advHandle = advHandle; + pMsg->numBis = numBis; + pMsg->sduInterval = sduInterval; + pMsg->maxSdu = maxSdu; + pMsg->mtlMs = mtlMs; + pMsg->rtn = rtn; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Stop a Broadcast Isochronous Group (BIG) identified for the given handle. + * + * \param bigHandle BIG identifier. + * \param reason Reason BIG is terminated. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigStop(uint8_t bigHandle, uint8_t reason) +{ + dmBisApiBigStop_t *pMsg; + + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + if ((pMsg = WsfMsgAlloc(sizeof(dmBisApiBigStop_t))) != NULL) + { + pMsg->hdr.event = DM_BIS_MSG_API_BIG_STOP; + pMsg->hdr.param = bigHandle; + pMsg->reason = reason; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the BIS is in use. + * + * \param handle BIS connection handle. + * + * \return TRUE if the BIS is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmBisInUse(uint16_t handle) +{ + dmBigCb_t *pBigCb = dmBigCb; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigCb++) + { + if (pBigCb->state == DM_BIS_SM_ST_IDLE) + { + continue; + } + + for (uint8_t j = 0; j < pBigCb->numBis; j++) + { + if (pBigCb->bisHandle[j] == handle) + { + return TRUE; + } + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Set the PHYs used for transmission of PDUs of Broadcast Isochronous Streams (BISes) in + * Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param phyBits PHY bit field. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetPhy(uint8_t bigHandle, uint8_t phyBits) +{ + const uint8_t MIN_PHY = 0x01; + const uint8_t MAX_PHY = 0x07; + + WSF_ASSERT(bigHandle < DM_BIG_MAX); + WSF_ASSERT((phyBits >= MIN_PHY) && (phyBits <= MAX_PHY)) + + WsfTaskLock(); + + dmBigCb[bigHandle].phyBits = phyBits; + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the packing scheme and framing format for the given Broadcast Isochronous Group + * (BIG). + * + * \param bigHandle BIG handle. + * \param packing Packing scheme. + * \param framing Indicates format of BIS Data PDUs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetPackingFraming(uint8_t bigHandle, uint8_t packing, uint32_t framing) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + WsfTaskLock(); + + dmBigCb[bigHandle].packing = packing; + dmBigCb[bigHandle].framing = framing; + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the Broadcast Code for the given Broadcast Isochronous Group (BIG). + * + * \param bigHandle BIG handle. + * \param encrypt FALSE (Unencrypted) or TRUE (Encrypted). + * \param authen FALSE (Unauthenticated) or TRUE (Authenticated). + * \param pBcastCode Broadcast code. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetBcastCode(uint8_t bigHandle, bool_t encrypt, bool_t authen, uint8_t *pBcastCode) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + + WsfTaskLock(); + + if (encrypt) + { + dmBigCb[bigHandle].encrypt = TRUE; + dmBigCb[bigHandle].authen = authen; + memcpy(dmBigCb[bigHandle].bcastCode, pBcastCode, HCI_BC_LEN); + } + else + { + dmBigCb[bigHandle].encrypt = FALSE; + dmBigCb[bigHandle].authen = FALSE; + memset(dmBigCb[bigHandle].bcastCode, 0x000, HCI_BC_LEN); + } + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG). + * + * \param bigHandle BIG handle. + * \param secLevel Security level. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBigSetSecLevel(uint8_t bigHandle, uint8_t secLevel) +{ + WSF_ASSERT(bigHandle < DM_BIG_MAX); + WSF_ASSERT(secLevel <= DM_SEC_LEVEL_BCAST_AUTH); + + WsfTaskLock(); + + dmBigCb[bigHandle].secLevel = secLevel; + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Get the security level of the LE Security Mode 3 for the given Broadcast Isochronous + * Group (BIG) connection handle. + * + * \param handle BIS connection handle. + * + * \return Security level. + */ +/*************************************************************************************************/ +uint8_t DmBigGetSecLevel(uint16_t handle) +{ + dmBigCb_t *pBigCb = dmBigCb; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigCb++) + { + if (pBigCb->state == DM_BIS_SM_ST_IDLE) + { + continue; + } + + for (uint8_t j = 0; j < pBigCb->numBis; j++) + { + if (pBigCb->bisHandle[j] == handle) + { + return pBigCb->secLevel; + } + } + } + + return DM_SEC_LEVEL_BCAST_NONE; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM BIS manager for operation as slave. + * + * \return None. + */ +/*************************************************************************************************/ +void DmBisSlaveInit(void) +{ + WsfTaskLock(); + + dmBigCb_t *pBigCb = dmBigCb; + + dmFcnIfTbl[DM_ID_BIS] = (dmFcnIf_t *) &dmBisFcnIf; + + for (uint8_t i = DM_BIG_MAX; i > 0; i--, pBigCb++) + { + dmBigCbInit(pBigCb); + } + + HciSetLeSupFeat((HCI_LE_SUP_FEAT_ISO_BROADCASTER | HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT), TRUE); + + WsfTaskUnlock(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.c new file mode 100644 index 00000000000..a9ec7af2f97 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.c @@ -0,0 +1,655 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Connected Isochronous Stream (CIS) management module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "util/bstream.h" +#include "dm_api.h" +#include "dm_dev.h" +#include "dm_main.h" +#include "dm_conn.h" +#include "dm_cis.h" + + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmCisReset(void); +static void dmCisMsgHandler(wsfMsgHdr_t *pMsg); +static void dmCisHciHandler(hciEvt_t *pEvent); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! Action set for CIS module */ +static const dmCisAct_t dmCisActSetMain[] = +{ + dmCisSmActNone, + dmCisSmActClose, + dmCisSmActCisEst, + dmCisSmActCisEstFailed, + dmCisSmActCisClosed, +}; + +/* CIS component function interface */ +static const dmFcnIf_t dmCisFcnIf = +{ + dmCisReset, + dmCisHciHandler, + dmCisMsgHandler +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/* Control block */ +dmCisCb_t dmCisCb; + +/*************************************************************************************************/ +/*! + * \brief Allocate a DM CIG control block. + * + * \param cigId CIG identifier. + * + * \return Pointer to CIG CB or NULL if failure. + */ +/*************************************************************************************************/ +dmCisCigCb_t *dmCisCigCbAlloc(uint8_t cigId) +{ + dmCisCigCb_t *pCigCb = dmCisCb.cisCigCb; + uint8_t i; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + for (i = 0; i < DM_CIG_MAX; i++, pCigCb++) + { + if (pCigCb->inUse == FALSE) + { + memset(pCigCb, 0, sizeof(dmCisCigCb_t)); + + pCigCb->cigId = cigId; + + /* set Cig default values */ + pCigCb->packing = HCI_PACKING_SEQUENTIAL; + pCigCb->framing = HCI_FRAMING_UNFRAMED; + pCigCb->sca = HCI_MIN_SCA; + pCigCb->sduIntervalMToS = pCigCb->sduIntervalSToM = HCI_DEFAULT_SDU_INTERV; + pCigCb->transLatMToS = pCigCb->transLatSToM = HCI_DEFAULT_CIS_TRANS_LAT; + pCigCb->inUse = TRUE; + + DM_TRACE_ALLOC1("dmCisCigCbAlloc cigId:%d", cigId); + + return pCigCb; + } + } + + DM_TRACE_ERR0("dmCisCigCbAlloc failed"); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a DM CIS connection control block. + * + * \param cigId Identfier of CIG that CIS belongs to. + * \param cisId CIS identfier. + * \param role Device role. + * + * \return Pointer to CIS CCB or NULL if failure. + */ +/*************************************************************************************************/ +dmCisCcb_t *dmCisCcbAlloc(uint8_t cigId, uint8_t cisId, uint8_t role) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t i; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + WSF_ASSERT(cisId < HCI_MAX_CIS_ID); + + for (i = 0; i < DM_CIS_MAX; i++, pCcb++) + { + if (pCcb->inUse == FALSE) + { + memset(pCcb, 0, sizeof(dmCisCcb_t)); + + pCcb->cigId = cigId; + pCcb->cisId = cisId; + pCcb->role = role; + pCcb->aclHandle = DM_CONN_HCI_HANDLE_NONE; + pCcb->cisHandle = DM_CONN_HCI_HANDLE_NONE; + pCcb->inUse = TRUE; + + DM_TRACE_ALLOC2("dmCisCcbAlloc cigId:%d cisId:%d", cigId, cisId); + + return pCcb; + } + } + + DM_TRACE_ERR0("dmCisCcbAlloc failed"); + + return NULL; +} + +/*************************************************************************************************/ +/*! +* \brief Deallocate a DM CIG control block. +* +* \param pCigCb CIG control block. +* +* \return None. +*/ +/*************************************************************************************************/ +void dmCisCigCbDealloc(dmCisCigCb_t *pCigCb) +{ + DM_TRACE_FREE1("dmCigCbDealloc %d", pCigCb->cigId); + + pCigCb->inUse = FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Deallocate a DM CIS connection control block. + * + * \param pCcb CIS connection control block. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisCcbDealloc(dmCisCcb_t *pCcb) +{ + DM_TRACE_FREE2("dmCisCcbDealloc cigId:%d cisId:%d", pCcb->cigId, pCcb->cisId); + + pCcb->inUse = FALSE; +} + +/*************************************************************************************************/ +/*! +* \brief Deallocate all CIS connection control blocks associated with the given CIG ID. +* +* \param cigId CIG identifer. +* +* \return None. +*/ +/*************************************************************************************************/ +void dmCisCcbDeallocByCigId(uint8_t cigId) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t i; + + for (i = DM_CIS_MAX; i > 0; i--, pCcb++) + { + if (pCcb->inUse && (pCcb->cigId == cigId)) + { + dmCisCcbDealloc(pCcb); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Find a CIS connection control block with matching handle. + * + * \param handle CIS connection handle. + * + * \return Pointer to CIS connection control block. NULL if not found. + */ +/*************************************************************************************************/ +dmCisCcb_t *dmCisCcbByHandle(uint16_t handle) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t i; + + for (i = DM_CIS_MAX; i > 0; i--, pCcb++) + { + if (pCcb->inUse && (pCcb->cisHandle == handle)) + { + return pCcb; + } + } + + DM_TRACE_INFO1("dmCisCcbByHandle not found %d", handle); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Return the CIS connection control block for the given CIG/CIS IDs. + * + * \param cigId CIG identifer. + * \param cisId CIS identifer. + * + * \return Pointer to CIS connection control block. NULL if not found. + */ +/*************************************************************************************************/ +dmCisCcb_t *dmCisCcbById(uint8_t cigId, uint8_t cisId) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t i; + + for (i = DM_CIS_MAX; i > 0; i--, pCcb++) + { + if (pCcb->inUse && (pCcb->cigId == cigId) && (pCcb->cisId == cisId)) + { + return pCcb; + } + } + + DM_TRACE_INFO2("dmCisCcbById not found cigId:%d cisId:%d", cigId, cisId); + + return NULL; +} + +/*************************************************************************************************/ +/*! +* \brief Return the CIG control block for the given CIG ID. +* +* \param cigId CIG identifer. +* +* \return Pointer to CIG control block. NULL if not found. +*/ +/*************************************************************************************************/ +dmCisCigCb_t *dmCisCigCbById(uint8_t cigId) +{ + dmCisCigCb_t *pCigCb = dmCisCb.cisCigCb; + uint8_t i; + + for (i = DM_CIG_MAX; i > 0; i--, pCigCb++) + { + if (pCigCb->inUse && (pCigCb->cigId == cigId)) + { + return pCigCb; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Empty action. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmActNone(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Close a CIS connection. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmActClose(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + /* close CIS connection */ + HciDisconnectCmd(pCcb->cisHandle, pMsg->apiClose.reason); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIS established event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmActCisEst(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + pMsg->hdr.event = DM_CIS_OPEN_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIS establish failure event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmActCisEstFailed(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + pMsg->hdr.event = DM_CIS_CLOSE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a disconnect complete event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmActCisClosed(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + pMsg->hdr.event = DM_CIS_CLOSE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + + +/*************************************************************************************************/ +/*! + * \brief Handle a CIS connection close event. + * + * \param aclHandle ACL connection handle. + * \param reason Reason. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisHandleConnClose(uint16_t aclHandle, uint8_t reason) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + hciDisconnectCmplEvt_t disconnectCmpl; + + /* generate HCI CIS disconnect complete event */ + disconnectCmpl.hdr.event = HCI_CIS_DISCONNECT_CMPL_CBACK_EVT; + disconnectCmpl.hdr.status = disconnectCmpl.status = HCI_SUCCESS; + disconnectCmpl.reason = reason; + + for (uint8_t i = DM_CIS_MAX; i > 0; i--, pCcb++) + { + if (!pCcb->inUse) + { + continue; + } + + if ((pCcb->aclHandle == aclHandle) || (aclHandle == DM_CONN_HCI_HANDLE_NONE)) + { + /* set Cis Id */ + disconnectCmpl.hdr.param = disconnectCmpl.handle = pCcb->cisHandle; + + /* handle the event */ + dmCisHciHandler((hciEvt_t *) &disconnectCmpl); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Reset the CIS module. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisReset(void) +{ + dmCisCigCb_t *pCigCb = dmCisCb.cisCigCb; + hciLeRemoveCigCmdCmplEvt_t removeCigCmdCmpl; + + dmCisHandleConnClose(DM_CONN_HCI_HANDLE_NONE, HCI_ERR_LOCAL_TERMINATED); + + /* generate HCI remove CIG command complete event */ + removeCigCmdCmpl.hdr.event = HCI_LE_REMOVE_CIG_CMD_CMPL_CBACK_EVT; + removeCigCmdCmpl.hdr.status = removeCigCmdCmpl.status = HCI_SUCCESS; + + for (uint8_t i = DM_CIG_MAX; i > 0; i--, pCigCb++) + { + if (pCigCb->inUse) + { + /* set Cig Id */ + removeCigCmdCmpl.hdr.param = removeCigCmdCmpl.cigId = pCigCb->cigId; + + /* handle the event */ + dmCisCigHciHandler((hciEvt_t *) &removeCigCmdCmpl); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM CIS WSF message handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmCisCcb_t *pCcb; + + /* look up ccb from cis handle */ + if ((pCcb = dmCisCcbByHandle(pMsg->param)) != NULL) + { + /* execute state machine */ + dmCisSmExecute(pCcb, (dmCisMsg_t *) pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief DM Conn HCI callback event handler. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisHciHandler(hciEvt_t *pEvent) +{ + dmCisCcb_t *pCcb = dmCisCcbByHandle(pEvent->hdr.param); + + /* handle special cases for CIS request event */ + if (pEvent->hdr.event == HCI_LE_CIS_REQ_CBACK_EVT) + { + /* first check if ccb exists for this handle */ + if (pCcb == NULL) + { + dmConnId_t connId; + + if ((connId = DmConnIdByHandle(pEvent->leCisReq.aclHandle)) != DM_CONN_ID_NONE) + { + /* if slave, allocate new ccb */ + if (DmConnRole(connId) == DM_ROLE_SLAVE) + { + pCcb = dmCisCcbAlloc(pEvent->leCisReq.cigId, pEvent->leCisReq.cisId, DM_ROLE_SLAVE); + } + } + } + + /* translate HCI event to state machine event */ + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_CIS_REQ; + } + else if (pEvent->hdr.event == HCI_LE_CIS_EST_CBACK_EVT) + { + /* translate HCI event to state machine event */ + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_CIS_EST; + } + else + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_CIS_EST_FAIL; + } + } + else /* HCI_CIS_DISCONNECT_CMPL_CBACK_EVT */ + { + /* translate HCI event to state machine event */ + pEvent->hdr.event = DM_CIS_MSG_HCI_DISCONNECT_CMPL; + } + + /* if ccb found */ + if (pCcb != NULL) + { + /* execute state machine */ + dmCisSmExecute(pCcb, (dmCisMsg_t *) pEvent); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisInit(void) +{ + WsfTaskLock(); + + dmFcnIfTbl[DM_ID_CIS] = (dmFcnIf_t *) &dmCisFcnIf; + dmCisActSet[DM_CIS_ACT_SET_MAIN] = (dmCisAct_t *) dmCisActSetMain; + + HciSetLeSupFeat(HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT, TRUE); + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Close the Connected Isochronous Stream (CIS) connection with the given handle. + * + * \param handle CIS connection handle. + * \param reason Reason connection is being closed. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisClose(uint16_t handle, uint8_t reason) +{ + dmCisApiClose_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(dmCisApiClose_t))) != NULL) + { + pMsg->hdr.event = DM_CIS_MSG_API_CLOSE; + pMsg->hdr.param = handle; + pMsg->hdr.status = pMsg->reason = reason; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Find the Connected Isochronous Stream (CIS) ID with matching + * handle. + * + * \param handle CIS identifer. + * + * \return CIS identifier or DM_CIS_ID_NONE if error. + */ +/*************************************************************************************************/ +uint8_t DmCisIdByHandle(uint16_t handle) +{ + dmCisCcb_t *pCcb; + + if ((pCcb = dmCisCcbByHandle(handle)) != NULL) + { + return pCcb->cisId; + } + + return DM_CIS_ID_NONE; +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the Connected Isochronous Stream (CIS) + * connection is in use. + * + * \param handle CIS connection handle. + * + * \return TRUE if the CIS connection is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmCisConnInUse(uint16_t handle) +{ + dmCisCcb_t *pCcb; + + if ((pCcb = dmCisCcbByHandle(handle)) != NULL) + { + return pCcb->inUse; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if Connected Isochronous Group (CIG) is in use. + * + * \param cigId CIG identifier. + * + * \return TRUE if CIG is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmCisCigInUse(uint8_t cigId) +{ + if (dmCisCigCbById(cigId) != NULL) + { + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief For internal use only. Return TRUE if the Connected Isochronous Stream (CIS) + * connection is in use. + * + * \param cigId CIG identifier. + * \param cisId CIS identifier. + * + * \return TRUE if the CIS connection is in use, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t DmCisInUse(uint8_t cigId, uint8_t cisId) +{ + if (dmCisCcbById(cigId, cisId) != NULL) + { + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.h new file mode 100644 index 00000000000..3995226fb39 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis.h @@ -0,0 +1,292 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Connected Isochronous Stream (CIS) management module. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#ifndef DM_CIS_H +#define DM_CIS_H + +#include "dm_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/* Uninitialized HCI handle */ +#define DM_CIS_HCI_HANDLE_NONE 0xFFFF + +/* Action set initializer */ +#define DM_CIS_ACT_SET_INIT(n) ((n) << 4) + +/* Get action set ID from action */ +#define DM_CIS_ACT_SET_ID(action) ((action) >> 4) + +/* Get action ID from action */ +#define DM_CIS_ACT_ID(action) ((action) & 0x0F) + +/* Restore old state */ +#define DM_CIS_SM_RESTORE_OLD_STATE 0xFF + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! DM CIS event handler messages for state machine */ +enum +{ + /* messages from API */ + DM_CIS_MSG_API_OPEN = DM_MSG_START(DM_ID_CIS), /*!< Open CIS Connection */ + DM_CIS_MSG_API_CLOSE, /*!< Close CIS Connection */ + DM_CIS_MSG_API_ACCEPT, /*!< Accept CIS Connection */ + DM_CIS_MSG_API_REJECT, /*!< Reject CIS Connection */ + + /* messages from HCI */ + DM_CIS_MSG_HCI_LE_CIS_EST_FAIL, /*!< HCI LE CIS Establish Failure Event */ + DM_CIS_MSG_HCI_LE_CIS_EST, /*!< HCI LE CIS Established Event */ + DM_CIS_MSG_HCI_DISCONNECT_CMPL, /*!< HCI Disconnection Complete Event */ + DM_CIS_MSG_HCI_LE_CIS_REQ /*!< HCI LE CIS Request Event */ +}; + +/* Number of CIS messages */ +#define DM_CIS_NUM_MSGS (DM_CIS_MSG_HCI_LE_CIS_REQ - DM_CIS_MSG_API_OPEN + 1) + +/* CIS state machine action function sets */ +enum +{ + DM_CIS_ACT_SET_MAIN, /*!< Main action functions */ + DM_CIS_ACT_SET_MASTER, /*!< Master action functions */ + DM_CIS_ACT_SET_SLAVE, /*!< Slave action functions */ + + DM_CIS_NUM_ACT_SETS +}; + +/*! CIS state machine actions */ +enum +{ + DM_CIS_SM_ACT_NONE = DM_CIS_ACT_SET_INIT(DM_CIS_ACT_SET_MAIN), /*!< No Action */ + DM_CIS_SM_ACT_CLOSE, /*!< Process Close */ + DM_CIS_SM_ACT_CIS_EST, /*!< Procoss CIS Established */ + DM_CIS_SM_ACT_CIS_EST_FAILED, /*!< Process CIS Establish Failed */ + DM_CIS_SM_ACT_CIS_CLOSED, /*!< Process CIS Closed */ + + DM_CIS_SM_ACT_OPEN = DM_CIS_ACT_SET_INIT(DM_CIS_ACT_SET_MASTER), /*!< Process Master Open */ + DM_CIS_SM_ACT_CANCEL_OPEN, /*!< Process Master Cancel Open */ + + DM_CIS_SM_ACT_REQUEST = DM_CIS_ACT_SET_INIT(DM_CIS_ACT_SET_SLAVE),/*!< Process Slave Request */ + DM_CIS_SM_ACT_ACCEPT, /*!< Process Slave Accept */ + DM_CIS_SM_ACT_REJECT, /*!< Process Slave Reject */ +}; + +/*! CIS state machine states */ +enum +{ + DM_CIS_SM_ST_IDLE, /*!< Idle State */ + DM_CIS_SM_ST_CONNECTING, /*!< Connecting State */ + DM_CIS_SM_ST_REQUESTING, /*!< Requesting State */ + DM_CIS_SM_ST_ACCEPTING, /*!< Accepting State */ + DM_CIS_SM_ST_CONNECTED, /*!< Connected State */ + DM_CIS_SM_ST_DISCONNECTING, /*!< Disconnecting State */ + + DM_CIS_SM_NUM_STATES +}; + +/*! DM CIS CIG event handler messages for state machine */ +enum +{ + /* messages from API */ + DM_CIS_CIG_MSG_API_CONFIG = DM_MSG_START(DM_ID_CIS_CIG), /*!< Configure CIG */ + DM_CIS_CIG_MSG_API_REMOVE, /*!< Remove CIG */ + + /* messages from HCI */ + DM_CIS_MSG_HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL, /*!< HCI LE Set CIG Parameters Command Complete Failure Event */ + DM_CIS_MSG_HCI_LE_SET_CIG_PARAMS_CMD_CMPL, /*!< HCI LE Set CIG Parameters Command Complete Event */ + DM_CIS_MSG_HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL, /*!< HCI LE Remove CIG Command Complete Failure Event */ + DM_CIS_MSG_HCI_LE_REMOVE_CIG_CMD_CMPL /*!< HCI LE Remove CIG Command Complete Event */ +}; + +/* Number of CIS CIG messages */ +#define DM_CIS_CIG_NUM_MSGS (DM_CIS_MSG_HCI_LE_REMOVE_CIG_CMD_CMPL - DM_CIS_CIG_MSG_API_CONFIG + 1) + +/*! CIS CIG state machine actions */ +enum +{ + DM_CIS_CIG_SM_ACT_NONE, /*!< No Action */ + DM_CIS_CIG_SM_ACT_CONFIG, /*!< Process Configure */ + DM_CIS_CIG_SM_ACT_CONFIGED, /*!< Process Configured */ + DM_CIS_CIG_SM_ACT_CONFIG_FAILED, /*!< Process Configure Failed */ + DM_CIS_CIG_SM_ACT_REMOVE, /*!< Process Remove */ + DM_CIS_CIG_SM_ACT_REMOVED, /*!< Process Removed */ + DM_CIS_CIG_SM_ACT_REMOVE_FAILED, /*!< Process Remove Failed */ +}; + +/*! CIS CIG state machine states */ +enum +{ + DM_CIS_CIG_SM_ST_IDLE, /*!< Idle State */ + DM_CIS_CIG_SM_ST_CONFIGING, /*!< Configuring State */ + DM_CIS_CIG_SM_ST_CONFIGED, /*!< Configured State */ + DM_CIS_CIG_SM_ST_REMOVING, /*!< Removing State */ + + DM_CIS_CIG_SM_NUM_STATES +}; + +/* Data structure for DM_CIS_CIG_MSG_API_CONFIG */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Message Header */ + uint8_t numCis; /*!< Number of CIS to be configured */ + HciCisCisParams_t *pCisParam; /*!< CIS parameters */ +} dmCisCigApiConfig_t; + +/* Data structure for DM_CIS_MSG_API_OPEN */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Message Header */ + uint8_t numCis; /*!< Total number of CISes to be created */ + uint16_t *pCisHandle; /*!< List of connection handles of CISes */ + uint16_t *pAclHandle; /*!< List of connection handles of ACLs */ +} dmCisApiOpen_t; + +/*! Data structure for DM_CIS_MSG_API_CLOSE */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Message Header */ + uint8_t reason; /*!< Reason connection is being closed */ +} dmCisApiClose_t; + +/*! Data structure for DM_CIS_MSG_API_REJECT */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Message Header */ + uint8_t reason; /*!< Reason CIS request was rejected */ +} dmCisApiReject_t; + +/*! Union of all DM CIS state machine messages */ +typedef union +{ + wsfMsgHdr_t hdr; /*!< Message Header */ + + /* API messages */ + dmCisCigApiConfig_t apiConfig; /*!< Configure CIG */ + dmCisApiOpen_t apiOpen; /*!< Open CIS Connection */ + dmCisApiClose_t apiClose; /*!< Close CIS Connection */ + dmCisApiReject_t apiReject; /*!< Reject CIS Connection */ + + /* HCI LE events */ + HciLeCisEstEvt_t hciLeCisEst; /*!< CIS Established */ + HciLeCisReqEvt_t hciLeCisReq; /*!< CIS Request */ + hciLeSetCigParamsCmdCmplEvt_t hciLeSetCigParamsCmdCmpl; /*!< Set CIS Parameters Command Complete */ + hciLeRemoveCigCmdCmplEvt_t hciLeRemoveCigCmdCmpl; /*!< Remove CIG Command Complete */ +} dmCisMsg_t; + +/*! CIS connection control block */ +typedef struct +{ + uint8_t cigId; /*!< Used to identify the connected isochronous group. */ + uint8_t cisId; /*!< Used to identify a connected isochronous stream. */ + uint16_t aclHandle; /*!< ACL handle. */ + uint16_t cisHandle; /*!< CIS handle. */ + dmConnId_t connId; /*!< DM connection ID */ + uint8_t role; /*!< Role. */ + uint8_t state; /*!< Main state. */ + uint8_t inUse; /*!< TRUE if entry in use. */ +} dmCisCcb_t; + +/*! CIS CIG control block */ +typedef struct +{ + uint8_t cigId; /*!< Used to identify the connected isochronous group. */ + uint32_t sduIntervalMToS; /*!< Time interval between the start of consecutive SDUs from the master Host (in usec). */ + uint32_t sduIntervalSToM; /*!< Time interval between the start of consecutive SDUs from the slave Host (in usec). */ + uint8_t sca; /*!< Sleep clock accuracy. */ + uint8_t packing; /*!< Packing scheme. */ + uint8_t framing; /*!< Indicates the format of CIS Data PDUs. */ + uint16_t transLatMToS; /*!< Maximum time for an SDU to be transported from the master Controller to slave Controller (in msec). */ + uint16_t transLatSToM; /*!< Maximum time for an SDU to be transported from the slave Controller to master Controller (in msec). */ + uint8_t numCis; /*!< Total number of CISes in the CIG being added or modified. */ + uint8_t cisId[DM_CIS_MAX]; /*!< List of CIS IDs being added or modified. */ + uint8_t state; /*!< Main state. */ + uint8_t inUse; /*!< TRUE if entry in use. */ +} dmCisCigCb_t; + +/*! Action functions */ +typedef void (*dmCisAct_t)(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +typedef void (*dmCisCigAct_t)(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); + +/*! Control block of the DM CIS module */ +typedef struct +{ + dmCisCcb_t cisCcb[DM_CIS_MAX]; /*!< CIS connection control block. */ + dmCisCigCb_t cisCigCb[DM_CIG_MAX]; /*!< CIS CIG control block. */ +} dmCisCb_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! State machine action sets */ +extern dmCisAct_t *dmCisActSet[DM_CIS_NUM_ACT_SETS]; + +/*! Action function table for CIG master module */ +extern const dmCisCigAct_t dmCisCigAct[]; + +/*! Control block */ +extern dmCisCb_t dmCisCb; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* utility functions */ +dmCisCigCb_t *dmCisCigCbAlloc(uint8_t cigId); +void dmCisCigCbDealloc(dmCisCigCb_t *pCigCb); +dmCisCcb_t *dmCisCcbAlloc(uint8_t cigId, uint8_t cisId, uint8_t role); +void dmCisCcbDealloc(dmCisCcb_t *pCcb); +void dmCisCcbDeallocByCigId(uint8_t cigId); +dmCisCcb_t *dmCisCcbByHandle(uint16_t handle); +dmCisCcb_t *dmCisCcbById(uint8_t cigId, uint8_t cisId); +dmCisCigCb_t *dmCisCigCbById(uint8_t cigId); + +/* CIS main action functions */ +void dmCisSmActClose(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +void dmCisSmActCisEst(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +void dmCisSmActCisEstFailed(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +void dmCisSmActCisClosed(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); + +/* CIG main action functions */ +void dmCisCigReset(void); +void dmCisCigMsgHandler(wsfMsgHdr_t *pMsg); +void dmCisCigHciHandler(hciEvt_t *pEvent); + +/* state machine */ +void dmCisSmExecute(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +void dmCisCigSmExecute(dmCisCigCb_t *pCcb, dmCisMsg_t *pMsg); + +/* main action functions */ +void dmCisSmActNone(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); + +#ifdef __cplusplus +}; +#endif + +#endif /* DM_CIS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_master.c new file mode 100644 index 00000000000..29517978fb5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_master.c @@ -0,0 +1,943 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Connected Isochronous Stream (CIS) management for master. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "dm_api.h" +#include "dm_dev.h" +#include "dm_main.h" +#include "dm_conn.h" +#include "dm_cis.h" + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmCisSmActOpen(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +static void dmCisSmActCancelOpen(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); + +static void dmCisCigSmActNone(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActConfig(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActConfiged(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActConfigFailed(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActRemove(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActRemoved(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); +static void dmCisCigSmActRemoveFailed(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/* Action set for CIS master module */ +static const dmCisAct_t dmCisActSetMaster[] = +{ + dmCisSmActOpen, + dmCisSmActCancelOpen +}; + +/* CIS CIG component function interface */ +static const dmFcnIf_t dmCisCigFcnIf = +{ + dmCisCigReset, + dmCisCigHciHandler, + dmCisCigMsgHandler +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! Action function table for CIG master module */ +const dmCisCigAct_t dmCisCigAct[] = +{ + dmCisCigSmActNone, + dmCisCigSmActConfig, + dmCisCigSmActConfiged, + dmCisCigSmActConfigFailed, + dmCisCigSmActRemove, + dmCisCigSmActRemoved, + dmCisCigSmActRemoveFailed +}; + +/*************************************************************************************************/ +/*! + * \brief Check if the CIS has already been created (established or is pending establishment). + * + * \param pCcb CIS connection control block. + * + * \return TRUE if CIS is created. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t dmCisCreated(dmCisCcb_t *pCcb) +{ + if ((pCcb->state == DM_CIS_SM_ST_CONNECTING) || (pCcb->state == DM_CIS_SM_ST_CONNECTED)) + { + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the CIS has pending to be established or disconnected. + * + * \param pCcb CIS connection control block. + * + * \return TRUE if CIS is created. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t dmCisPending(dmCisCcb_t *pCcb) +{ + if ((pCcb->state == DM_CIS_SM_ST_CONNECTING) || (pCcb->state == DM_CIS_SM_ST_DISCONNECTING)) + { + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available CISes. + * + * \param None. + * + * \return Number of available CISes. + */ +/*************************************************************************************************/ +uint8_t dmCisNumAvail(void) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t i, cnt; + + for (i = DM_CIS_MAX, cnt = 0; i > 0; i--, pCcb++) + { + if (pCcb->inUse == FALSE) + { + cnt++; + } + } + + return cnt; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CISes that are pending to be established or disconnected. + * + * \param pCcb CIS connection control block. + * + * \return Number of CISes that are already set up (enabled). + */ +/*************************************************************************************************/ +uint8_t dmCisNumPending(dmCisCcb_t *pCcb) +{ + dmCisCcb_t *pCisCcb = dmCisCb.cisCcb; + uint8_t i, cnt; + + for (i = DM_CIS_MAX, cnt = 0; i > 0; i--, pCisCcb++) + { + if (pCisCcb->inUse && (pCisCcb != pCcb) && dmCisPending(pCisCcb)) + { + cnt++; + } + } + + return cnt; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CISes that are already set up (enabled) for the given CIG). + * + * \param cigId CIG identifier. + * \param numCis Number of CISes. + * \param pCisParam Set CIG CIS parameters. + * + * \return Number of CISes that are already set up (enabled). + */ +/*************************************************************************************************/ +static uint8_t dmCisNumEnabled(uint8_t cigId, uint8_t numCis, HciCisCisParams_t *pCisParam) +{ + uint8_t i, cnt; + + for (i = numCis, cnt = 0; i > 0; i--, pCisParam++) + { + if (dmCisCcbById(cigId, pCisParam->cisId) != NULL) + { + cnt++; + } + } + + return cnt; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS connetions that are created for the given CIG. + * + * \param cigId CIG identifier. + * \param numCis Number of CISes. + * \param pCisParam Set CIG CIS parameters. + * + * \return Number of CIS connections that are created. + */ +/*************************************************************************************************/ +uint8_t dmCisNumCreatedByCigId(uint8_t cigId, uint8_t numCis, HciCisCisParams_t *pCisParam) +{ + uint8_t i, cnt; + + for (i = numCis, cnt = 0; i > 0; i--, pCisParam++) + { + dmCisCcb_t *pCcb; + + if ((pCcb = dmCisCcbById(cigId, pCisParam->cisId)) != NULL) + { + if (dmCisCreated(pCcb)) + { + cnt++; + } + } + } + + return cnt; +} + +/*************************************************************************************************/ +/*! + * \brief Empty action. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActNone(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Configure (set) CIG parameters for the given CIG. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActConfig(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + dmCisCigApiConfig_t *pConfig = &pMsg->apiConfig; + uint8_t status = HCI_SUCCESS; + + /* if none of the CISes in the CIG have been created */ + if (dmCisNumCreatedByCigId(pCigCb->cigId, pConfig->numCis, pConfig->pCisParam) == 0) + { + uint8_t numEnabled; + + if ((numEnabled = dmCisNumEnabled(pCigCb->cigId, pConfig->numCis, pConfig->pCisParam)) == 0) + { + /* Set up new CISes. */ + if (pConfig->numCis <= dmCisNumAvail()) + { + pCigCb->numCis = pConfig->numCis; + + for (uint8_t i = 0; i < pConfig->numCis; i++) + { + dmCisCcbAlloc(pCigCb->cigId, pConfig->pCisParam[i].cisId, DM_ROLE_MASTER); + + /* remember CIS IDs being added or modified */ + pCigCb->cisId[i] = pConfig->pCisParam[i].cisId; + } + } + else + { + DM_TRACE_WARN0("dmCisCigSmActConfig: there isn't enough CISes available"); + status = HCI_ERR_CONN_LIMIT; + } + } + else + { + if ((pConfig->numCis - numEnabled) <= dmCisNumAvail()) + { + pCigCb->numCis = pConfig->numCis; + + for (uint8_t i = 0; i < pConfig->numCis; i++) + { + /* allocate entries only for new CISes */ + if (dmCisCcbById(pCigCb->cigId, pConfig->pCisParam[i].cisId) == NULL) + { + dmCisCcbAlloc(pCigCb->cigId, pConfig->pCisParam[i].cisId, DM_ROLE_MASTER); + } + + /* remember CIS IDs being added or modified */ + pCigCb->cisId[i] = pConfig->pCisParam[i].cisId; + } + } + else + { + DM_TRACE_WARN0("dmCisCigSmActConfig: there isn't enough CISes available"); + status = HCI_ERR_CONN_LIMIT; + } + } + } + else + { + DM_TRACE_WARN0("dmCisCigSmActConfig: there're CISes already created"); + status = HCI_ERR_CMD_DISALLOWED; + } + + if (status == HCI_SUCCESS) + { + HciCisCigParams_t cigParam; + + cigParam.cigId = pCigCb->cigId; + cigParam.sduIntervalMToS = pCigCb->sduIntervalMToS; + cigParam.sduIntervalSToM = pCigCb->sduIntervalSToM; + cigParam.sca = pCigCb->sca; + cigParam.packing = pCigCb->packing; + cigParam.framing = pCigCb->framing; + cigParam.transLatMToS = pCigCb->transLatMToS; + cigParam.transLatSToM = pCigCb->transLatSToM; + cigParam.numCis = pMsg->apiConfig.numCis; + cigParam.pCisParam = pMsg->apiConfig.pCisParam; + + /* set CIG parameters */ + HciLeSetCigParamsCmd(&cigParam); + } + else + { + pMsg->hdr.status = status; + + /* notify app about failure */ + dmCisCigSmActConfigFailed(pCigCb, pMsg); + + /* restore old state */ + pCigCb->state = DM_CIS_SM_RESTORE_OLD_STATE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIG configured event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActConfiged(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + /* store connection handles of CISes that have been created */ + for (uint8_t i = 0; i < pMsg->hciLeSetCigParamsCmdCmpl.numCis; i++) + { + dmCisCcb_t *pCcb; + + if ((pCcb = dmCisCcbById(pCigCb->cigId, pCigCb->cisId[i])) != NULL) + { + pCcb->cisHandle = pMsg->hciLeSetCigParamsCmdCmpl.cisHandle[i]; + } + } + + pMsg->hdr.event = DM_CIS_CIG_CONFIG_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIG configure failure event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActConfigFailed(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + if (pCigCb->state != DM_CIS_CIG_SM_ST_CONFIGED) + { + dmCisCigCbDealloc(pCigCb); + } + + pMsg->hdr.event = DM_CIS_CIG_CONFIG_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Remove CIG parameters for the given CIG. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActRemove(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + dmCisCcb_t *pCcb = dmCisCb.cisCcb; + uint8_t status = HCI_SUCCESS; + + /* if none of the CISes in the CIG have been established or is pending establishment */ + for (uint8_t i = DM_CIS_MAX; i > 0; i--, pCcb++) + { + if ((pCcb->inUse == TRUE) && (pCcb->cigId == pCigCb->cigId)) + { + /* if CIS in slave role */ + if (pCcb->role == DM_ROLE_SLAVE) + { + DM_TRACE_WARN0("dmCisCigSmActRemove: invalid role"); + status = HCI_ERR_CMD_DISALLOWED; + break; + } + + /* if any CIS in the CIG has already been established or is pending establishment */ + if (dmCisCreated(pCcb)) + { + DM_TRACE_WARN0("dmCisCigSmActRemove: there're CISes established or pending establishment"); + status = HCI_ERR_CMD_DISALLOWED; + break; + } + } + } + + if (status == HCI_SUCCESS) + { + /* remove CIG */ + HciLeRemoveCigCmd(pCigCb->cigId); + } + else + { + pMsg->hdr.status = status; + + /* notify app about failure */ + dmCisCigSmActRemoveFailed(pCigCb, pMsg); + + /* restore old state */ + pCigCb->state = DM_CIS_SM_RESTORE_OLD_STATE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIG removed event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActRemoved(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + /* deallocate associated CIS and CIG control blocks */ + dmCisCcbDeallocByCigId(pCigCb->cigId); + dmCisCigCbDealloc(pCigCb); + + pMsg->hdr.event = DM_CIS_CIG_REMOVE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a CIG remove failure event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisCigSmActRemoveFailed(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + pMsg->hdr.event = DM_CIS_CIG_REMOVE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Open a CIS connection. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisSmActOpen(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + dmCisApiOpen_t *pOpen = &pMsg->apiOpen; + uint8_t status = HCI_SUCCESS; + + /* if the previous create CIS isn't pending or hasn't been cancelled */ + if (dmCisNumPending(pCcb) == 0) + { + for (uint8_t i = 0; i < pOpen->numCis; i++) + { + dmConnCcb_t *pConnCcb; + + /* if the ACL connection handle doesn't exist */ + if ((pConnCcb = dmConnCcbByHandle(pOpen->pAclHandle[i])) == NULL) + { + DM_TRACE_WARN1("dmCisSmActOpen: ACL handle not found (handle:%d)", pOpen->pAclHandle[i]); + status = HCI_ERR_UNKNOWN_HANDLE; + break; + } + + /* if slave */ + if (pConnCcb->role == DM_ROLE_SLAVE) + { + DM_TRACE_WARN0("dmCisSmActOpen: invalid role"); + status = HCI_ERR_CMD_DISALLOWED; + break; + } + + /* if the CIS connection handle does not exist */ + if (dmCisCcbByHandle(pOpen->pCisHandle[i]) == NULL) + { + DM_TRACE_WARN1("dmCisSmActOpen: CIS handle not found (handle:%d)", pOpen->pCisHandle[i]); + status = HCI_ERR_UNKNOWN_HANDLE; + break; + } + } + } + else + { + DM_TRACE_WARN0("dmCisSmActOpen: there're CISes pending to be established or disconnected"); + status = HCI_ERR_CMD_DISALLOWED; + } + + if (status == HCI_SUCCESS) + { + HciCisCreateCisParams_t createCisParam; + + createCisParam.pAclHandle = pOpen->pAclHandle; + createCisParam.pCisHandle = pOpen->pCisHandle; + + /* create CIS */ + HciLeCreateCisCmd(pOpen->numCis, &createCisParam); + + /* set new state and ACL handle for all CISes */ + for (uint8_t i = 0; i < pOpen->numCis; i++) + { + dmCisCcb_t *pCisCcb; + + if ((pCisCcb = dmCisCcbByHandle(pOpen->pCisHandle[i])) != NULL) + { + pCisCcb->state = pCcb->state; + pCisCcb->aclHandle = pOpen->pAclHandle[i]; + } + } + } + else + { + pMsg->hdr.status = status; + + /* notify app about failure */ + dmCisSmActCisEstFailed(pCcb, pMsg); + + /* restore old state */ + pCcb->state = DM_CIS_SM_RESTORE_OLD_STATE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Cancel a CIS opening connection. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisSmActCancelOpen(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + /* cancel CIS create connection */ + HciDisconnectCmd(pMsg->hdr.param, pMsg->apiClose.reason); +} + +/*************************************************************************************************/ +/*! + * \brief Reset the CIS CIG module. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisCigReset(void) +{ + dmCisCigCb_t *pCigCb = dmCisCb.cisCigCb; + uint8_t i; + + for (i = 0; i < DM_CIG_MAX; i++, pCigCb++) + { + if (pCigCb->inUse) + { + dmCisCcbDeallocByCigId(pCigCb->cigId); + dmCisCigCbDealloc(pCigCb); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM CIS CIG WSF message handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisCigMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmCisCigCb_t *pCigCb; + + /* look up cb from cig id */ + if ((pCigCb = dmCisCigCbById((uint8_t) pMsg->param)) != NULL) + { + /* execute state machine */ + dmCisCigSmExecute(pCigCb, (dmCisMsg_t *) pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief DM CIS CIG HCI callback event handler. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisCigHciHandler(hciEvt_t *pEvent) +{ + dmCisCigCb_t *pCigCb = dmCisCigCbById((uint8_t) pEvent->hdr.param); + + /* translate HCI event to state machine event */ + if (pEvent->hdr.event == HCI_LE_SET_CIG_PARAMS_CMD_CMPL_CBACK_EVT) + { + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_SET_CIG_PARAMS_CMD_CMPL; + } + else + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL; + } + } + else /* HCI_LE_REMOVE_CIG_CMD_CMPL_CBACK_EVT */ + { + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_REMOVE_CIG_CMD_CMPL; + } + else + { + pEvent->hdr.event = DM_CIS_MSG_HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL; + } + } + + /* if cig cb found */ + if (pCigCb != NULL) + { + /* execute state machine */ + dmCisCigSmExecute(pCigCb, (dmCisMsg_t *) pEvent); + } +} + +/*************************************************************************************************/ +/*! + * \brief Set the parameters of one or more Connected Isochronous Streams (CISes) that are + * associated with the given Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * \param numCis Number of CIS to be configured. + * \param pCisParam CIS parameters. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigConfig(uint8_t cigId, dmConnId_t numCis, HciCisCisParams_t *pCisParam) +{ + dmCisCigCb_t *pCigCb = NULL; + dmCisCigApiConfig_t *pMsg; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + WSF_ASSERT((numCis > 0 ) && (numCis <= DM_CIS_MAX)); + + /* make sure Cig cb not already allocated */ + WsfTaskLock(); + if ((pCigCb = dmCisCigCbById(cigId)) == NULL) + { + /* allocate Cig cb */ + pCigCb = dmCisCigCbAlloc(cigId); + } + WsfTaskUnlock(); + + if (pCigCb != NULL) + { + if ((pMsg = WsfMsgAlloc(sizeof(dmCisCigApiConfig_t) + (numCis * sizeof(HciCisCisParams_t)))) != NULL) + { + pMsg->hdr.event = DM_CIS_CIG_MSG_API_CONFIG; + pMsg->hdr.param = cigId; + pMsg->numCis = numCis; + pMsg->pCisParam = (HciCisCisParams_t *) (pMsg + 1); + + memcpy(pMsg->pCisParam, pCisParam, (numCis * sizeof(HciCisCisParams_t))); + + WsfMsgSend(dmCb.handlerId, pMsg); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Remove all the Connected Isochronous Streams (CISes) associated with the given + * Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigRemove(uint8_t cigId) +{ + wsfMsgHdr_t *pMsg; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + if ((pMsg = WsfMsgAlloc(sizeof(wsfMsgHdr_t))) != NULL) + { + pMsg->event = DM_CIS_CIG_MSG_API_REMOVE; + pMsg->param = cigId; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Create one or more Connected Isochronous Streams (CISes) using the connections + * identified by the ACL connection handles. + * + * \param numCis Total number of CISes to be created. + * \param pCisHandle List of connection handles of CISes. + * \param pAclHandle List of connection handles of ACLs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisOpen(uint8_t numCis, uint16_t *pCisHandle, uint16_t *pAclHandle) +{ + dmCisApiOpen_t *pMsg; + + WSF_ASSERT((numCis > 0 ) && (numCis <= DM_CIS_MAX)); + + if ((pMsg = WsfMsgAlloc(sizeof(dmCisApiOpen_t) + (numCis * 2 * sizeof(uint16_t)))) != NULL) + { + pMsg->hdr.event = DM_CIS_MSG_API_OPEN; + pMsg->hdr.param = pCisHandle[0]; + pMsg->numCis = numCis; + + pMsg->pCisHandle = (uint16_t *) (pMsg + 1); + memcpy(pMsg->pCisHandle, pCisHandle, (numCis * sizeof(uint16_t))); + + pMsg->pAclHandle = (uint16_t *) (pMsg->pCisHandle + numCis); + memcpy(pMsg->pAclHandle, pAclHandle, (numCis * sizeof(uint16_t))); + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Set the interval, in microseconds, of periodic SDUs for the given Connected Isochronous + * Group (CIG). + * + * \param cigId CIG ID. + * \param sduIntervalMToS Time interval between start of consecutive SDUs from master Host. + * \param sduIntervalSToM Time interval between start of consecutive SDUs from slave Host. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetSduInterval(uint8_t cigId, uint32_t sduIntervalMToS, uint32_t sduIntervalSToM) +{ + dmCisCigCb_t *pCigCb; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + /* make sure Cig cb not already allocated */ + WsfTaskLock(); + if ((pCigCb = dmCisCigCbById(cigId)) == NULL) + { + /* allocate Cig cb */ + pCigCb = dmCisCigCbAlloc(cigId); + } + + if (pCigCb != NULL) + { + pCigCb->sduIntervalMToS = sduIntervalMToS; + pCigCb->sduIntervalSToM = sduIntervalSToM; + } + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the slaves clock accuracy for the given Connected Isochronous Group (CIG). + * + * \param cigId CIG identifier. + * \param sca Slaves clck accuracy (0 if unknown). + * + * \return None. + * + * \note The slaves clock accuracy must which must be the worst-case sleep clock accuracy of the + * slaves that will participate in the CIG. + */ +/*************************************************************************************************/ +void DmCisCigSetSca(uint8_t cigId, uint8_t sca) +{ + dmCisCigCb_t *pCigCb; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + /* make sure Cig cb not already allocated */ + WsfTaskLock(); + if ((pCigCb = dmCisCigCbById(cigId)) == NULL) + { + /* allocate Cig cb */ + pCigCb = dmCisCigCbAlloc(cigId); + } + + if (pCigCb != NULL) + { + pCigCb->sca = sca; + } + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the packing scheme and framing format for the given Connected Isochronous Group + * (CIG). + * + * \param cigId CIG identifier. + * \param packing Packing scheme. + * \param framing Indicates format of CIS Data PDUs. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetPackingFraming(uint8_t cigId, uint8_t packing, uint32_t framing) +{ + dmCisCigCb_t *pCigCb; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + /* make sure Cig cb not already allocated */ + WsfTaskLock(); + if ((pCigCb = dmCisCigCbById(cigId)) == NULL) + { + /* allocate Cig cb */ + pCigCb = dmCisCigCbAlloc(cigId); + } + + if (pCigCb != NULL) + { + pCigCb->packing = packing; + pCigCb->framing = framing; + } + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Set the maximum transport latency, in microseconds, for the given Connected Isochronous + * Group (CIG). + * + * \param cigId CIG identifier. + * \param transLatMToS Maximum time for SDU to be transported from master Controller to slave Controller. + * \param transLatSToM Maximum time for SDU to be transported from slave Controller to master Controller. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisCigSetTransLatInterval(uint8_t cigId, uint16_t transLatMToS, uint16_t transLatSToM) +{ + dmCisCigCb_t *pCigCb; + + WSF_ASSERT(cigId < HCI_MAX_CIG_ID); + + /* make sure Cig cb not already allocated */ + WsfTaskLock(); + if ((pCigCb = dmCisCigCbById(cigId)) == NULL) + { + /* allocate Cig cb */ + pCigCb = dmCisCigCbAlloc(cigId); + } + + if (pCigCb != NULL) + { + pCigCb->transLatMToS = transLatMToS; + pCigCb->transLatSToM = transLatSToM; + } + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager for operation as master. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisMasterInit(void) +{ + WsfTaskLock(); + + dmFcnIfTbl[DM_ID_CIS_CIG] = (dmFcnIf_t *) &dmCisCigFcnIf; + dmCisActSet[DM_CIS_ACT_SET_MASTER] = (dmCisAct_t *) dmCisActSetMaster; + + HciSetLeSupFeat(HCI_LE_SUP_FEAT_CIS_MASTER, TRUE); + + WsfTaskUnlock(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_slave.c new file mode 100644 index 00000000000..77441b545dd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_slave.c @@ -0,0 +1,187 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Connected Isochronous Stream (CIS) management for slave. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_msg.h" +#include "dm_api.h" +#include "dm_main.h" +#include "dm_conn.h" +#include "dm_adv.h" +#include "dm_cis.h" + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmCisSmActRequest(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +static void dmCisSmActAccept(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); +static void dmCisSmActReject(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/* Action set for this module */ +static const dmCisAct_t dmCisActSetSlave[] = +{ + dmCisSmActRequest, + dmCisSmActAccept, + dmCisSmActReject +}; + +/*************************************************************************************************/ +/*! + * \brief Handle a CIS request event from HCI. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisSmActRequest(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + /* save CIS and ACL handles */ + pCcb->cisHandle = pMsg->hciLeCisReq.cisHandle; + pCcb->aclHandle = pMsg->hciLeCisReq.aclHandle; + + pMsg->hdr.event = DM_CIS_REQ_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Accept a requested CIS connection. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisSmActAccept(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + /* if slave */ + if (pCcb->role == DM_ROLE_SLAVE) + { + /* accept CIS */ + HciLeAcceptCisReqCmd(pMsg->hdr.param); + } + else + { + /* deallocate ccb */ + dmCisCcbDealloc(pCcb); + } +} + +/*************************************************************************************************/ +/*! + * \brief Reject a requested CIS connection. + * + * \param pCcb CIS connection control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmCisSmActReject(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + /* if slave */ + if (pCcb->role == DM_ROLE_SLAVE) + { + /* reject CIS */ + HciLeRejectCisReqCmd(pMsg->hdr.param, pMsg->apiReject.reason); + } + + /* deallocate ccb */ + dmCisCcbDealloc(pCcb); +} + +/*************************************************************************************************/ +/*! + * \brief Inform the Controller to accept the request for the Connected Isochronous Stream (CIS) + * that is identified by the connection handle. + * + * \param handle Connection handle of the CIS. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisAccept(uint16_t handle) +{ + wsfMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(wsfMsgHdr_t))) != NULL) + { + pMsg->event = DM_CIS_MSG_API_ACCEPT; + pMsg->param = handle; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Inform the Controller to reject the request for the Connected Isochronous Stream (CIS) + * that is identified by the connection handle. + * + * \param handle Connection handle of the CIS to be rejected. + * \param reason Reason the CIS request was rejected. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisReject(uint16_t handle, uint8_t reason) +{ + dmCisApiReject_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(dmCisApiReject_t))) != NULL) + { + pMsg->hdr.event = DM_CIS_MSG_API_REJECT; + pMsg->hdr.param = handle; + pMsg->hdr.status = pMsg->reason = reason; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM Connected Isochronous Stream (CIS) manager for operation as slave. + * + * \return None. + */ +/*************************************************************************************************/ +void DmCisSlaveInit(void) +{ + WsfTaskLock(); + + dmCisActSet[DM_CIS_ACT_SET_SLAVE] = (dmCisAct_t *) dmCisActSetSlave; + + HciSetLeSupFeat(HCI_LE_SUP_FEAT_CIS_SLAVE, TRUE); + + WsfTaskUnlock(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_sm.c new file mode 100644 index 00000000000..d7c54b8b247 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_cis_sm.c @@ -0,0 +1,263 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Connected Isochronous Stream (CIS) management state machine. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "dm_api.h" +#include "dm_main.h" +#include "dm_conn.h" +#include "dm_cis.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! Column position of next state */ +#define DM_CIS_NEXT_STATE 0 + +/*! Column position of action */ +#define DM_CIS_ACTION 1 + +/*! Number of columns in the state machine state tables */ +#define DM_CIS_NUM_COLS 2 + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! DM CIS state machine state tables */ +static const uint8_t dmCisStateTbl[DM_CIS_SM_NUM_STATES][DM_CIS_NUM_MSGS][DM_CIS_NUM_COLS] = +{ + /* Idle state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_CONNECTING, DM_CIS_SM_ACT_OPEN}, + /* API_CLOSE */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_NONE}, + /* API_ACCEPT */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_NONE}, + /* API_REJECT */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_CIS_EST}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_REQUEST} + }, + /* Connecting state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_CONNECTING, DM_CIS_SM_ACT_NONE}, + /* API_CLOSE */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_CANCEL_OPEN}, + /* API_ACCEPT */ {DM_CIS_SM_ST_CONNECTING, DM_CIS_SM_ACT_NONE}, + /* API_REJECT */ {DM_CIS_SM_ST_CONNECTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_EST_FAILED}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_CIS_EST}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_EST_FAILED}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_CONNECTING, DM_CIS_SM_ACT_NONE} + }, + /* Requested state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE}, + /* API_CLOSE */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE}, + /* API_ACCEPT */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_ACCEPT}, + /* API_REJECT */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_REJECT}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_REQUESTING, DM_CIS_SM_ACT_NONE} + }, + /* Accepting state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_NONE}, + /* API_CLOSE */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_NONE}, + /* API_ACCEPT */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_NONE}, + /* API_REJECT */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_EST_FAILED}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_CIS_EST}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_EST_FAILED}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_ACCEPTING, DM_CIS_SM_ACT_NONE} + }, + /* Connected state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE}, + /* API_CLOSE */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_CLOSE}, + /* API_ACCEPT */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE}, + /* API_REJECT */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_CLOSED}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_CONNECTED, DM_CIS_SM_ACT_NONE} + }, + /* Disconnecting state */ + { + /* Event Next state Action */ + /* API_OPEN */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE}, + /* API_CLOSE */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE}, + /* API_ACCEPT */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE}, + /* API_REJECT */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL_FAIL */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_CIS_EST_CMD_CMPL */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_CLOSE}, + /* HCI_DISCONNECT_CMPL */ {DM_CIS_SM_ST_IDLE, DM_CIS_SM_ACT_CIS_CLOSED}, + /* HCI_LE_CIS_REQ */ {DM_CIS_SM_ST_DISCONNECTING, DM_CIS_SM_ACT_NONE} + } +}; + +/*! DM CIS CIG state machine state tables */ +static const uint8_t dmCisCigStateTbl[DM_CIS_CIG_SM_NUM_STATES][DM_CIS_CIG_NUM_MSGS][DM_CIS_NUM_COLS] = +{ + /* Idle state */ + { + /* Event Next state Action */ + /* API_CONFIG */ {DM_CIS_CIG_SM_ST_CONFIGING, DM_CIS_CIG_SM_ACT_CONFIG}, + /* API_REMOVE */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIGED}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_NONE} + }, + /* Configuring state */ + { + /* Event Next state Action */ + /* API_CONFIG */ {DM_CIS_CIG_SM_ST_CONFIGING, DM_CIS_CIG_SM_ACT_NONE}, + /* API_REMOVE */ {DM_CIS_CIG_SM_ST_CONFIGING, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_CONFIG_FAILED}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIGED}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_CONFIGING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_CONFIG_FAILED} + }, + /* Configured state */ + { + /* Event Next state Action */ + /* API_CONFIG */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIG}, + /* API_REMOVE */ {DM_CIS_CIG_SM_ST_REMOVING, DM_CIS_CIG_SM_ACT_REMOVE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIG_FAILED}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIGED}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_CONFIG_FAILED}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_REMOVED} + }, + /* Removing state */ + { + /* Event Next state Action */ + /* API_CONFIG */ {DM_CIS_CIG_SM_ST_REMOVING, DM_CIS_CIG_SM_ACT_NONE}, + /* API_REMOVE */ {DM_CIS_CIG_SM_ST_REMOVING, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_REMOVING, DM_CIS_CIG_SM_ACT_NONE}, + /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL */ {DM_CIS_CIG_SM_ST_REMOVING, DM_CIS_CIG_SM_ACT_REMOVE}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL_FAIL */ {DM_CIS_CIG_SM_ST_CONFIGED, DM_CIS_CIG_SM_ACT_REMOVE_FAILED}, + /* HCI_LE_REMOVE_CIG_CMD_CMPL */ {DM_CIS_CIG_SM_ST_IDLE, DM_CIS_CIG_SM_ACT_REMOVED} + } +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! State machine action set array */ +dmCisAct_t *dmCisActSet[DM_CIS_NUM_ACT_SETS]; + +/*************************************************************************************************/ +/*! + * \brief Execute the DM CIS connection state machine. + * + * \param pCcb CIS connection control block. + * \param pMsg State machine message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmCisSmExecute(dmCisCcb_t *pCcb, dmCisMsg_t *pMsg) +{ + dmCisAct_t *actSet; + uint8_t action; + uint8_t event; + uint8_t state = pCcb->state; + + DM_TRACE_INFO2("dmCisSmExecute event=%d state=%d", pMsg->hdr.event, state); + + /* get the event */ + event = DM_MSG_MASK(pMsg->hdr.event); + + /* get action */ + action = dmCisStateTbl[state][event][DM_CIS_ACTION]; + + /* set next state */ + pCcb->state = dmCisStateTbl[state][event][DM_CIS_NEXT_STATE]; + + /* look up action set */ + actSet = dmCisActSet[DM_CIS_ACT_SET_ID(action)]; + + /* if action set present */ + if (actSet != NULL) + { + /* execute action function in action set */ + (*actSet[DM_CIS_ACT_ID(action)])(pCcb, pMsg); + } + else + { + /* no action */ + dmCisSmActNone(pCcb, pMsg); + } + + /* if restore old state requested */ + if (pCcb->inUse && (pCcb->state == DM_CIS_SM_RESTORE_OLD_STATE)) + { + pCcb->state = state; + } +} + +/*************************************************************************************************/ +/*! +* \brief Execute the DM CIS CIG state machine. +* +* \param pCigCb CIG control block. +* \param pMsg WSF message. +* +* \return None. +*/ +/*************************************************************************************************/ +void dmCisCigSmExecute(dmCisCigCb_t *pCigCb, dmCisMsg_t *pMsg) +{ + uint8_t action; + uint8_t event; + uint8_t state = pCigCb->state; + + DM_TRACE_INFO2("dmCisCigSmExecute event=%d state=%d", pMsg->hdr.event, state); + + /* get the event */ + event = DM_MSG_MASK(pMsg->hdr.event); + + /* get action */ + action = dmCisCigStateTbl[state][event][DM_CIS_ACTION]; + + /* set next state */ + pCigCb->state = dmCisCigStateTbl[state][event][DM_CIS_NEXT_STATE]; + + /* execute action function */ + (*dmCisCigAct[action])(pCigCb, pMsg); + + /* if restore old state requested */ + if (pCigCb->inUse && (pCigCb->state == DM_CIS_SM_RESTORE_OLD_STATE)) + { + pCigCb->state = state; + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.c index fd600d0f945..746a7c107ac 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager connection management module. + * \file + * + * \brief Device manager connection management module. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -65,6 +67,12 @@ static const dmConnAct_t dmConnActSetMain[] = dmConnSmActHciUpdated }; +/* Action set for Connection Update module */ +static const dmConnAct_t dmConnUpdActSetMain[] = +{ + dmConnUpdActNone +}; + /* Component function interface */ static const dmFcnIf_t dmConnFcnIf = { @@ -81,10 +89,31 @@ static const dmFcnIf_t dmConn2FcnIf = dmConn2MsgHandler }; +/* Connection update function interface */ +static const dmFcnIf_t dmConnUpdFcnIf = +{ + dmEmptyReset, + (dmHciHandler_t) dmEmptyHandler, + dmConnUpdMsgHandler +}; + +/*! Connection update action table */ +static const uint8_t dmConnUpdActTbl[DM_CONN_UPD_NUM_MSGS] = +{ + /* Event Action */ + /* API_UPDATE_MASTER */ DM_CONN_UPD_ACT_UPDATE_MASTER, + /* API_UPDATE_SLAVE */ DM_CONN_UPD_ACT_UPDATE_SLAVE, + /* L2C_UPDATE_IND */ DM_CONN_UPD_ACT_L2C_UPDATE_IND, + /* L2C_UPDATE_CNF */ DM_CONN_UPD_ACT_L2C_UPDATE_CNF +}; + /************************************************************************************************** Global Variables **************************************************************************************************/ +/*! Connection update action set array */ +dmConnAct_t *dmConnUpdActSet[DM_CONN_NUM_ACT_SETS]; + /* Control block */ dmConnCb_t dmConnCb; @@ -98,6 +127,7 @@ static void dmConn2ActWriteAuthToCmpl(dmConnCcb_t *pCcb, hciEvt_t *pEvent); static void dmConn2ActAuthToExpired(dmConnCcb_t *pCcb, hciEvt_t *pEvent); static void dmConn2ActReadRemoteFeaturesCmpl(dmConnCcb_t *pCcb, hciEvt_t *pEvent); static void dmConn2ActReadRemoteVerInfoCmpl(dmConnCcb_t *pCcb, hciEvt_t *pEvent); +static void dmConn2ActReqPeerSca(dmConnCcb_t *pCcb, hciEvt_t *pEvent); /*************************************************************************************************/ /*! @@ -338,7 +368,8 @@ dmConnId_t dmConnOpenAccept(uint8_t clientId, uint8_t initPhys, uint8_t advHandl if (pCcb != NULL) { - if ((pMsg = WsfMsgAlloc(sizeof(dmConnApiOpen_t))) != NULL) + // Allocate sizeof(dmConnMsg_t) because message may be reused in state machine with different callbacks + if ((pMsg = WsfMsgAlloc(sizeof(dmConnMsg_t))) != NULL) { pMsg->hdr.param = pCcb->connId; pMsg->hdr.event = (role == DM_ROLE_MASTER) ? @@ -549,6 +580,57 @@ void dmConnSmActHciUpdated(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) (*dmConnCb.connCback[DM_CLIENT_ID_APP])((dmEvt_t *) pMsg); } +/*************************************************************************************************/ +/*! + * \brief Empty action. + * + * \param pMsg WSF message. + * \param pCcb Connection control block. + * + * \return None. + */ +/*************************************************************************************************/ +void dmConnUpdActNone(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Execute the DM connection update action. + * + * \param pCcb Connection control block. + * \param pMsg Event message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmConnUpdExecute(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +{ + dmConnAct_t *actSet; + uint8_t action; + + DM_TRACE_INFO2("dmConnUpdExecute event=%d state=%d", pMsg->hdr.event, pCcb->state); + + /* get action */ + action = dmConnUpdActTbl[DM_MSG_MASK(pMsg->hdr.event)]; + + /* look up action set */ + actSet = dmConnUpdActSet[DM_CONN_ACT_SET_ID(action)]; + + /* if action set present */ + if (actSet != NULL) + { + /* execute action function in action set */ + (*actSet[DM_CONN_ACT_ID(action)])(pCcb, pMsg); + } + else + { + /* no action */ + dmConnUpdActNone(pCcb, (dmConnMsg_t *) pMsg); + } +} + /*************************************************************************************************/ /*! * \brief Reset the scan module. @@ -724,6 +806,10 @@ void dmConn2MsgHandler(wsfMsgHdr_t *pMsg) HciWriteAuthPayloadTimeout(pCcb->handle, pConn2Msg->apiWriteAuthPayloadTo.timeout); break; + case DM_CONN_MSG_API_REQ_PEER_SCA: + HciLeRequestPeerScaCmd(pCcb->handle); + break; + default: /* should never get here */ break; @@ -778,6 +864,10 @@ void dmConn2HciHandler(hciEvt_t *pEvent) dmConn2ActReadRemoteVerInfoCmpl(pCcb, pEvent); break; + case HCI_LE_REQ_PEER_SCA_CBACK_EVT: + dmConn2ActReqPeerSca(pCcb, pEvent); + break; + default: /* should never get here */ break; @@ -785,6 +875,31 @@ void dmConn2HciHandler(hciEvt_t *pEvent) } } +/*************************************************************************************************/ +/*! + * \brief DM Conn update WSF message handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmConnUpdMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmConnCcb_t *pCcb; + + /* look up ccb from conn id */ + if ((pCcb = dmConnCcbById((dmConnId_t) pMsg->param)) != NULL) + { + /* if connected */ + if (pCcb->state == DM_CONN_SM_ST_CONNECTED) + { + /* execute connection update action */ + dmConnUpdExecute(pCcb, (dmConnMsg_t *) pMsg); + } + } +} + /*************************************************************************************************/ /*! * \brief Handle a read RSSI event from HCI. @@ -968,6 +1083,30 @@ static void dmConn2ActReadRemoteVerInfoCmpl(dmConnCcb_t *pCcb, hciEvt_t *pEvent) (*dmConnCb.connCback[DM_CLIENT_ID_APP])((dmEvt_t *) &evt); } +/*************************************************************************************************/ +/*! +* \brief Handle a request peer SCA event from HCI. +* +* \param pCcb Connection control block. +* \param pEvent Pointer to HCI callback event structure. +* +* \return None. +*/ +/*************************************************************************************************/ +static void dmConn2ActReqPeerSca(dmConnCcb_t *pCcb, hciEvt_t *pEvent) +{ + HciLeReqPeerScaCmplEvt_t_t evt; + + /* call callback */ + evt.hdr.event = DM_REQ_PEER_SCA_IND; + evt.hdr.param = pCcb->connId; + evt.status = evt.hdr.status = (uint8_t) pEvent->leReqPeerSca.status; + evt.handle = pCcb->handle; + evt.peerSca = pEvent->leReqPeerSca.peerSca; + + (*dmConnCb.connCback[DM_CLIENT_ID_APP])((dmEvt_t *) &evt); +} + /*************************************************************************************************/ /*! * \brief Initialize DM connection manager. @@ -977,9 +1116,16 @@ static void dmConn2ActReadRemoteVerInfoCmpl(dmConnCcb_t *pCcb, hciEvt_t *pEvent) /*************************************************************************************************/ void DmConnInit(void) { + WsfTaskLock(); + dmFcnIfTbl[DM_ID_CONN] = (dmFcnIf_t *) &dmConnFcnIf; dmFcnIfTbl[DM_ID_CONN_2] = (dmFcnIf_t *) &dmConn2FcnIf; + dmFcnIfTbl[DM_ID_CONN_UPD] = (dmFcnIf_t *) &dmConnUpdFcnIf; + dmConnActSet[DM_CONN_ACT_SET_MAIN] = (dmConnAct_t *) dmConnActSetMain; + dmConnUpdActSet[DM_CONN_ACT_SET_MAIN] = (dmConnAct_t *) dmConnUpdActSetMain; + + WsfTaskUnlock(); } /*************************************************************************************************/ @@ -1017,7 +1163,8 @@ void DmConnClose(uint8_t clientId, dmConnId_t connId, uint8_t reason) { dmConnApiClose_t *pMsg; - if ((pMsg = WsfMsgAlloc(sizeof(dmConnApiClose_t))) != NULL) + // Allocate sizeof(dmConnMsg_t) because message may be reused in state machine with different callbacks + if ((pMsg = WsfMsgAlloc(sizeof(dmConnMsg_t))) != NULL) { pMsg->hdr.event = DM_CONN_MSG_API_CLOSE; pMsg->hdr.param = connId; @@ -1049,6 +1196,8 @@ void DmReadRemoteFeatures(dmConnId_t connId) hciLeReadRemoteFeatCmplEvt_t evt; uint8_t *p = evt.features; + memset(&evt, 0, sizeof(hciLeReadRemoteFeatCmplEvt_t)); + /* call callback */ evt.hdr.event = DM_REMOTE_FEATURES_IND; evt.hdr.param = pCcb->connId; @@ -1103,7 +1252,8 @@ void DmConnUpdate(dmConnId_t connId, hciConnSpec_t *pConnSpec) { dmConnApiUpdate_t *pMsg; - if ((pMsg = WsfMsgAlloc(sizeof(dmConnApiUpdate_t))) != NULL) + // Allocate sizeof(dmConnMsg_t) because message may be reused in state machine with different callbacks + if ((pMsg = WsfMsgAlloc(sizeof(dmConnMsg_t))) != NULL) { pMsg->hdr.event = (DmConnRole(connId) == DM_ROLE_MASTER) ? DM_CONN_MSG_API_UPDATE_MASTER : DM_CONN_MSG_API_UPDATE_SLAVE; @@ -1365,6 +1515,28 @@ void DmWriteAuthPayloadTimeout(dmConnId_t connId, uint16_t timeout) } } +/*************************************************************************************************/ +/*! + * \brief Request the Sleep Clock Accuracy (SCA) of a peer device. + * + * \param connId Connection identifier. + * + * \return None. + */ +/*************************************************************************************************/ +void DmConnRequestPeerSca(dmConnId_t connId) +{ + dmConnApiReqPeerSca_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(dmConnApiReqPeerSca_t))) != NULL) + { + pMsg->hdr.event = DM_CONN_MSG_API_REQ_PEER_SCA; + pMsg->hdr.param = connId; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + /*************************************************************************************************/ /*! * \brief For internal use only. Find the connection ID with matching handle. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.h index 8cb97b0e01e..09b3b29c79a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM connection management module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM connection management module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_CONN_H @@ -55,12 +57,6 @@ enum DM_CONN_MSG_API_OPEN = DM_MSG_START(DM_ID_CONN), /*!< Open Connection */ DM_CONN_MSG_API_CLOSE, /*!< Close Connection */ DM_CONN_MSG_API_ACCEPT, /*!< Accept Connection */ - DM_CONN_MSG_API_UPDATE_MASTER, /*!< Master Connection Parameter Update */ - DM_CONN_MSG_API_UPDATE_SLAVE, /*!< Slave Connecteion Parameter Update */ - - /* messages from L2C */ - DM_CONN_MSG_L2C_UPDATE_IND, /*!< L2CAP Parameter update indication */ - DM_CONN_MSG_L2C_UPDATE_CNF, /*!< L2CAP Parameter update confirmation */ /* messages from HCI */ DM_CONN_MSG_HCI_LE_CONN_CMPL_FAIL, /*!< HCI LE Connection Complete Failure Event */ @@ -68,13 +64,10 @@ enum DM_CONN_MSG_HCI_DISCONNECT_CMPL, /*!< HCI Disconnection Complete Event */ DM_CONN_MSG_HCI_LE_CONN_UPDATE_CMPL, /*!< HCI LE Connection Update Complete Event */ DM_CONN_MSG_HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL, /*!< HCI LE Create Connection Cancel Command Complet Event */ - - /* other internal messages */ - DM_CONN_MSG_INT_UPDATE_TIMEOUT /*!< Internal Update Timeout */ }; /* Number of messages */ -#define DM_CONN_NUM_MSGS (DM_CONN_MSG_INT_UPDATE_TIMEOUT - DM_CONN_MSG_API_OPEN + 1) +#define DM_CONN_NUM_MSGS (DM_CONN_MSG_HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL - DM_CONN_MSG_API_OPEN + 1) /* DM conn event handler messages, non-state machine */ enum @@ -85,12 +78,24 @@ enum DM_CONN_MSG_API_REM_CONN_PARAM_REQ_NEG_REPLY, DM_CONN_MSG_API_SET_DATA_LEN, DM_CONN_MSG_API_WRITE_AUTH_TO, + DM_CONN_MSG_API_REQ_PEER_SCA +}; - /* messages from HCI */ - DM_CONN_MSG_HCI_READ_RSSI_CMPL, - DM_CONN_MSG_HCI_FEAT_CMPL +/*! DM conn event handler messages for connection update */ +enum +{ + /* messages from API */ + DM_CONN_MSG_API_UPDATE_MASTER = DM_MSG_START(DM_ID_CONN_UPD), /*!< Master Connection Parameter Update */ + DM_CONN_MSG_API_UPDATE_SLAVE, /*!< Slave Connecteion Parameter Update */ + + /* messages from L2C */ + DM_CONN_MSG_L2C_UPDATE_IND, /*!< L2CAP Parameter update indication */ + DM_CONN_MSG_L2C_UPDATE_CNF, /*!< L2CAP Parameter update confirmation */ }; +/* Number of messages */ +#define DM_CONN_UPD_NUM_MSGS (DM_CONN_MSG_L2C_UPDATE_CNF - DM_CONN_MSG_API_UPDATE_MASTER + 1) + /* State machine action function sets */ enum { @@ -112,15 +117,23 @@ enum DM_CONN_SM_ACT_OPEN = DM_CONN_ACT_SET_INIT(DM_CONN_ACT_SET_MASTER), /*!< Process Master Connection Open */ DM_CONN_SM_ACT_CANCEL_OPEN, /*!< Process Master Cancel Connection Open */ - DM_CONN_SM_ACT_UPDATE_MASTER, /*!< Process Master Connection Parameter Update */ - DM_CONN_SM_ACT_L2C_UPDATE_IND, /*!< Process Master L2CAP Connection Parameter Update Indication */ DM_CONN_SM_ACT_ACCEPT = DM_CONN_ACT_SET_INIT(DM_CONN_ACT_SET_SLAVE), /*!< Process Slave Connection Accept */ DM_CONN_SM_ACT_CANCEL_ACCEPT, /*!< Process Slave Cancel Connection Accept */ - DM_CONN_SM_ACT_UPDATE_SLAVE, /*!< Process Slave Connection Update */ DM_CONN_SM_ACT_CONN_ACCEPTED, /*!< Process Slave Connection Accepted */ - DM_CONN_SM_ACT_ACCEPT_FAILED, /*!< Process Slave Connection Accept Failure */ - DM_CONN_SM_ACT_L2C_UPDATE_CNF /*!< Process Slave L2CAP Connection Parameter Update Confirmation */ + DM_CONN_SM_ACT_ACCEPT_FAILED /*!< Process Slave Connection Accept Failure */ +}; + +/*! Connection update actions */ +enum +{ + DM_CONN_UPD_ACT_NONE = DM_CONN_ACT_SET_INIT(DM_CONN_ACT_SET_MAIN), /*!< No Action */ + + DM_CONN_UPD_ACT_UPDATE_MASTER = DM_CONN_ACT_SET_INIT(DM_CONN_ACT_SET_MASTER), /*!< Process Master Connection Parameter Update */ + DM_CONN_UPD_ACT_L2C_UPDATE_IND, /*!< Process Master L2CAP Connection Parameter Update Indication */ + + DM_CONN_UPD_ACT_UPDATE_SLAVE = DM_CONN_ACT_SET_INIT(DM_CONN_ACT_SET_SLAVE), /*!< Process Slave Connection Update */ + DM_CONN_UPD_ACT_L2C_UPDATE_CNF /*!< Process Slave L2CAP Connection Parameter Update Confirmation */ }; /*! State machine states */ @@ -236,6 +249,12 @@ typedef struct uint16_t timeout; } dmConnApiWriteAuthPayloadTo_t; +/*! Data structure for DM_CONN_MSG_API_REQ_PEER_SCA */ +typedef struct +{ + wsfMsgHdr_t hdr; +} dmConnApiReqPeerSca_t; + /*! Union of all DM Conn 2 messages */ typedef union { @@ -246,6 +265,7 @@ typedef union dmConnApiRemConnParamReqNegReply_t apiRemConnParamReqNegReply; dmConnApiSetDataLen_t apiSetDataLen; dmConnApiWriteAuthPayloadTo_t apiWriteAuthPayloadTo; + dmConnApiReqPeerSca_t apiReqPeerSca; } dmConn2Msg_t; /*! Connection control block */ @@ -294,6 +314,15 @@ typedef struct /*! State machine action sets */ extern dmConnAct_t *dmConnActSet[DM_CONN_NUM_ACT_SETS]; +/*! Connection update action sets */ +extern dmConnAct_t *dmConnUpdActSet[DM_CONN_NUM_ACT_SETS]; + +/* Action set for master connection update */ +extern const dmConnAct_t dmConnUpdActSetMaster[]; + +/* Action set for slave connection update */ +extern const dmConnAct_t dmConnUpdActSetSlave[]; + /*! Control block */ extern dmConnCb_t dmConnCb; @@ -322,9 +351,15 @@ void dmConnHciHandler(hciEvt_t *pEvent); void dmConn2MsgHandler(wsfMsgHdr_t *pMsg); void dmConn2HciHandler(hciEvt_t *pEvent); +/* connection update inteface */ +void dmConnUpdMsgHandler(wsfMsgHdr_t *pMsg); + /* state machine */ void dmConnSmExecute(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); +/* connection update action execute */ +void dmConnUpdExecute(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); + /* main action functions */ void dmConnSmActNone(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); void dmConnSmActClose(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); @@ -333,10 +368,15 @@ void dmConnSmActConnFailed(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); void dmConnSmActConnClosed(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); void dmConnSmActHciUpdated(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); +/* connection update main action function */ +void dmConnUpdActNone(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); + /* common master action functions */ void dmConnSmActCancelOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); -void dmConnSmActUpdateMaster(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); -void dmConnSmActL2cUpdateInd(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); + +/* connection update common master action functions */ +void dmConnUpdActUpdateMaster(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); +void dmConnUpdActL2cUpdateInd(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); /* legacy master action functions */ void dmConnSmActOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); @@ -344,9 +384,9 @@ void dmConnSmActOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); /* extended master action functions */ void dmExtConnSmActOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); -/* common slave action functions */ -void dmConnSmActUpdateSlave(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); -void dmConnSmActL2cUpdateCnf(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); +/* connection update common slave action functions */ +void dmConnUpdActUpdateSlave(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); +void dmConnUpdActL2cUpdateCnf(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); /* legacy slave action functions */ void dmConnSmActAccept(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_cte.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_cte.c index 6ab52c88091..86824ea9f53 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_cte.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_cte.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ +/*************************************************************************************************/ /*! - * \brief Device manager Connection Constant Tone Extension (CTE) module. + * \file + * + * \brief Device manager Connection Constant Tone Extension (CTE) module. + * + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,21 +32,6 @@ #include "dm_main.h" #include "dm_conn.h" -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/*! DM connection CTE states */ -enum -{ - DM_CONN_CTE_STATE_IDLE, /*!< Idle */ - DM_CONN_CTE_STATE_INITIATING, /*!< Initiating CTE request */ - DM_CONN_CTE_STATE_RESPONDING, /*!< Responding to CTE request */ - DM_CONN_CTE_STATE_SAMPLING, /*!< Sampling received CTE */ - DM_CONN_CTE_STATE_STARTING, /*!< Starting CTE request, CTE response or sampling received CTE */ - DM_CONN_CTE_STATE_STOPPING, /*!< Stopping CTE request, CTE response or sampling received CTE */ -}; - /************************************************************************************************** Data Types **************************************************************************************************/ @@ -213,11 +200,17 @@ void dmConnCteInit(void) /*************************************************************************************************/ void DmConnCteInit(void) { + WsfTaskLock(); + /* set function interface table */ dmFcnIfTbl[DM_ID_CONN_CTE] = (dmFcnIf_t *) &dmConnCteFcnIf; /* initialize control block */ dmConnCteInit(); + + HciSetLeSupFeat((HCI_LE_SUP_FEAT_CONN_CTE_REQ | HCI_LE_SUP_FEAT_CONN_CTE_RSP), TRUE); + + WsfTaskUnlock(); } /*************************************************************************************************/ @@ -836,3 +829,35 @@ void DmReadAntennaInfo(void) { HciLeReadAntennaInfoCmd(); } + +/*************************************************************************************************/ +/*! + * \brief Returns the device manager's CTE request state for a given connection. + * + * \param connId Connection identifier. + * + * \return The CTE request state. + */ +/*************************************************************************************************/ +uint8_t DmConnCteGetReqState(dmConnId_t connId) +{ + WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX)); + + return dmConnCteCb[connId-1].reqState; +} + +/*************************************************************************************************/ +/*! + * \brief Returns the device manager's CTE response state for a given connection. + * + * \param connId Connection identifier. + * + * \return The CTE response state. + */ +/*************************************************************************************************/ +uint8_t DmConnCteGetRspState(dmConnId_t connId) +{ + WSF_ASSERT((connId > DM_CONN_ID_NONE) && (connId <= DM_CONN_MAX)); + + return dmConnCteCb[connId-1].rspState; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master.c index a84182160ad..d92f3e7ee4f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management for master. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management for master. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,6 +31,17 @@ #include "dm_conn.h" #include "l2c_api.h" +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/* Action set for this module */ +const dmConnAct_t dmConnUpdActSetMaster[] = +{ + dmConnUpdActUpdateMaster, + dmConnUpdActL2cUpdateInd +}; + /*************************************************************************************************/ /*! * \brief Cancel an opening connection. @@ -58,7 +71,7 @@ void dmConnSmActCancelOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) * \return None. */ /*************************************************************************************************/ -void dmConnSmActUpdateMaster(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +void dmConnUpdActUpdateMaster(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) { /* send HCI command */ HciLeConnUpdateCmd(pCcb->handle, &pMsg->apiUpdate.connSpec); @@ -74,7 +87,7 @@ void dmConnSmActUpdateMaster(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) * \return None. */ /*************************************************************************************************/ -void dmConnSmActL2cUpdateInd(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +void dmConnUpdActL2cUpdateInd(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) { /* always send back response */ L2cDmConnUpdateRsp(pMsg->l2cUpdateInd.identifier, pCcb->handle, L2C_CONN_PARAM_ACCEPTED); @@ -105,7 +118,7 @@ void DmL2cConnUpdateInd(uint8_t identifier, uint16_t handle, hciConnSpec_t *pCon updateInd.pConnSpec = pConnSpec; updateInd.identifier = identifier; - dmConnSmExecute(pCcb, (dmConnMsg_t *) &updateInd); + dmConnUpdExecute(pCcb, (dmConnMsg_t *) &updateInd); } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_ae.c index f3d0b41903d..cdb8b025f28 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management module for extended master. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management module for extended master. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,9 +36,7 @@ static const dmConnAct_t dmConnActSetMaster[] = { dmExtConnSmActOpen, - dmConnSmActCancelOpen, - dmConnSmActUpdateMaster, - dmConnSmActL2cUpdateInd + dmConnSmActCancelOpen }; /*************************************************************************************************/ @@ -112,5 +112,10 @@ void dmExtConnSmActOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) /*************************************************************************************************/ void DmExtConnMasterInit(void) { + WsfTaskLock(); + dmConnActSet[DM_CONN_ACT_SET_MASTER] = (dmConnAct_t *) dmConnActSetMaster; + dmConnUpdActSet[DM_CONN_ACT_SET_MASTER] = (dmConnAct_t *) dmConnUpdActSetMaster; + + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_leg.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_leg.c index a47dbd3c91b..bdf160b21e5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_leg.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_master_leg.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management module for legacy master. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management module for legacy master. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,9 +36,7 @@ Local Variables static const dmConnAct_t dmConnActSetMaster[] = { dmConnSmActOpen, - dmConnSmActCancelOpen, - dmConnSmActUpdateMaster, - dmConnSmActL2cUpdateInd + dmConnSmActCancelOpen }; /*************************************************************************************************/ @@ -86,5 +86,10 @@ void dmConnSmActOpen(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) /*************************************************************************************************/ void DmConnMasterInit(void) { + WsfTaskLock(); + dmConnActSet[DM_CONN_ACT_SET_MASTER] = (dmConnAct_t *) dmConnActSetMaster; + dmConnUpdActSet[DM_CONN_ACT_SET_MASTER] = (dmConnAct_t *) dmConnUpdActSetMaster; + + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave.c index cd6b87c16fb..9422ae8e45e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager slave connection management for slave. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager slave connection management for slave. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -28,6 +30,17 @@ #include "dm_adv.h" #include "l2c_api.h" +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/* Action set for this module */ +const dmConnAct_t dmConnUpdActSetSlave[] = +{ + dmConnUpdActUpdateSlave, + dmConnUpdActL2cUpdateCnf +}; + /*************************************************************************************************/ /*! * \brief Call application callback with the connection update complete event. @@ -60,7 +73,7 @@ static void dmConnUpdateCback(dmConnCcb_t *pCcb, uint8_t status) * \return None. */ /*************************************************************************************************/ -void dmConnSmActUpdateSlave(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +void dmConnUpdActUpdateSlave(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) { if ((pCcb->features & HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC) && (HciGetLeSupFeat() & HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC)) @@ -93,7 +106,7 @@ void dmConnSmActUpdateSlave(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) * \return None. */ /*************************************************************************************************/ -void dmConnSmActL2cUpdateCnf(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) +void dmConnUpdActL2cUpdateCnf(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) { /* if connection update in progress */ if (pCcb->updating) @@ -130,7 +143,7 @@ void DmL2cConnUpdateCnf(uint16_t handle, uint16_t result) updateCnf.hdr.event = DM_CONN_MSG_L2C_UPDATE_CNF; updateCnf.result = result; - dmConnSmExecute(pCcb, (dmConnMsg_t *) &updateCnf); + dmConnUpdExecute(pCcb, (dmConnMsg_t *) &updateCnf); } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_ae.c index 9993934efbf..bb52ff3355e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management for extended slave. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management for extended slave. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,10 +39,8 @@ static const dmConnAct_t dmConnActSetSlave[] = { dmExtConnSmActAccept, dmExtConnSmActCancelAccept, - dmConnSmActUpdateSlave, dmExtConnSmActConnAccepted, - dmExtConnSmActAcceptFailed, - dmConnSmActL2cUpdateCnf + dmExtConnSmActAcceptFailed }; /*************************************************************************************************/ @@ -120,5 +120,10 @@ void dmExtConnSmActAcceptFailed(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) /*************************************************************************************************/ void DmExtConnSlaveInit(void) { + WsfTaskLock(); + dmConnActSet[DM_CONN_ACT_SET_SLAVE] = (dmConnAct_t *) dmConnActSetSlave; + dmConnUpdActSet[DM_CONN_ACT_SET_SLAVE] = (dmConnAct_t *) dmConnUpdActSetSlave; + + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_leg.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_leg.c index 2607e1e9e5a..d714da9f52f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_leg.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_slave_leg.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management for legacy slave. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management for legacy slave. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,10 +39,8 @@ static const dmConnAct_t dmConnActSetSlave[] = { dmConnSmActAccept, dmConnSmActCancelAccept, - dmConnSmActUpdateSlave, dmConnSmActConnAccepted, - dmConnSmActAcceptFailed, - dmConnSmActL2cUpdateCnf + dmConnSmActAcceptFailed }; /*************************************************************************************************/ @@ -119,5 +119,10 @@ void dmConnSmActAcceptFailed(dmConnCcb_t *pCcb, dmConnMsg_t *pMsg) /*************************************************************************************************/ void DmConnSlaveInit(void) { + WsfTaskLock(); + dmConnActSet[DM_CONN_ACT_SET_SLAVE] = (dmConnAct_t *) dmConnActSetSlave; + dmConnUpdActSet[DM_CONN_ACT_SET_SLAVE] = (dmConnAct_t *) dmConnUpdActSetSlave; + + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_sm.c index c4ff8bffaf1..58c5c6e1e4d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_sm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_conn_sm.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager connection management state machine. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager connection management state machine. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -53,16 +55,11 @@ static const uint8_t dmConnStateTbl[DM_CONN_SM_NUM_STATES][DM_CONN_NUM_MSGS][DM_ /* API_OPEN */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_OPEN}, /* API_CLOSE */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, /* API_ACCEPT */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_ACCEPT}, - /* API_UPDATE_MASTER */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_SLAVE */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_IND */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_CNF */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL_FAIL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_CONN_ACCEPTED}, /* HCI_DISCONNECT_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_UPDATE_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, - /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE}, - /* INT_UPDATE_TIMEOUT */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE} + /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_NONE} }, /* Connecting state */ { @@ -70,16 +67,11 @@ static const uint8_t dmConnStateTbl[DM_CONN_SM_NUM_STATES][DM_CONN_NUM_MSGS][DM_ /* API_OPEN */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, /* API_CLOSE */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_CANCEL_OPEN}, /* API_ACCEPT */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_MASTER */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_SLAVE */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_IND */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_CNF */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL_FAIL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CONN_FAILED}, /* HCI_LE_CONN_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_CONN_OPENED}, /* HCI_DISCONNECT_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CONN_FAILED}, /* HCI_LE_CONN_UPDATE_CMPL */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE}, - /* INT_UPDATE_TIMEOUT */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE} + /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_CONNECTING, DM_CONN_SM_ACT_NONE} }, /* Accepting state */ { @@ -87,16 +79,11 @@ static const uint8_t dmConnStateTbl[DM_CONN_SM_NUM_STATES][DM_CONN_NUM_MSGS][DM_ /* API_OPEN */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, /* API_CLOSE */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CANCEL_ACCEPT}, /* API_ACCEPT */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_MASTER */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_SLAVE */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_IND */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_CNF */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL_FAIL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_ACCEPT_FAILED}, /* HCI_LE_CONN_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_CONN_ACCEPTED}, /* HCI_DISCONNECT_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_ACCEPT_FAILED}, /* HCI_LE_CONN_UPDATE_CMPL */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE}, - /* INT_UPDATE_TIMEOUT */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE} + /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_ACCEPTING, DM_CONN_SM_ACT_NONE} }, /* Connected state */ { @@ -104,16 +91,11 @@ static const uint8_t dmConnStateTbl[DM_CONN_SM_NUM_STATES][DM_CONN_NUM_MSGS][DM_ /* API_OPEN */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE}, /* API_CLOSE */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_CLOSE}, /* API_ACCEPT */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_MASTER */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_UPDATE_MASTER}, - /* API_UPDATE_SLAVE */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_UPDATE_SLAVE}, - /* L2C_UPDATE_IND */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_L2C_UPDATE_IND}, - /* L2C_UPDATE_CNF */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_L2C_UPDATE_CNF}, /* HCI_LE_CONN_CMPL_FAIL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE}, /* HCI_DISCONNECT_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CONN_CLOSED}, /* HCI_LE_CONN_UPDATE_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_HCI_UPDATED}, - /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE}, - /* INT_UPDATE_TIMEOUT */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_HCI_UPDATED} + /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_CONNECTED, DM_CONN_SM_ACT_NONE} }, /* Disconnecting state */ { @@ -121,16 +103,11 @@ static const uint8_t dmConnStateTbl[DM_CONN_SM_NUM_STATES][DM_CONN_NUM_MSGS][DM_ /* API_OPEN */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, /* API_CLOSE */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, /* API_ACCEPT */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_MASTER */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* API_UPDATE_SLAVE */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_IND */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* L2C_UPDATE_CNF */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, /* HCI_LE_CONN_CMPL_FAIL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CONN_CLOSED}, /* HCI_LE_CONN_CMPL */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_CLOSE}, /* HCI_DISCONNECT_CMPL */ {DM_CONN_SM_ST_IDLE, DM_CONN_SM_ACT_CONN_CLOSED}, /* HCI_LE_CONN_UPDATE_CMPL */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE}, - /* INT_UPDATE_TIMEOUT */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE} + /* HCI_LE_CREATE_CONN_CANCEL_CMD_CMPL */ {DM_CONN_SM_ST_DISCONNECTING, DM_CONN_SM_ACT_NONE} } }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c index abc1a89dbb9..492e44573e9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief DM local device management module. + * \file + * + * \brief DM local device management module. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.h index 7b4fbb94766..aaa575aff55 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM local device management module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM local device management module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_DEV_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev_priv.c index f5c3b0fd643..fe1af93bc23 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev_priv.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager device privacy module. + * \file + * + * \brief Device manager device privacy module. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -513,9 +515,9 @@ void dmDevPrivActCtrl(dmDevPrivMsg_t *pMsg) WSF_ASSERT(pMsg->privCtrl.advHandle < DM_NUM_ADV_SETS); /* clear advertising set */ - /* note: advertising handle is checked before reaching this function */ - /* coverity[overrun-buffer-arg] */ - memset(&dmDevPrivCb.extAdv[pMsg->privCtrl.advHandle], 0, sizeof(dmDevPrivExtAdv_t)); + dmDevPrivCb.extAdv[pMsg->privCtrl.advHandle].configured = FALSE; + dmDevPrivCb.extAdv[pMsg->privCtrl.advHandle].connectable = FALSE; + dmDevPrivCb.extAdv[pMsg->privCtrl.advHandle].advertising = FALSE; break; case DM_DEV_PRIV_MSG_ADV_SETS_CLEAR: @@ -604,10 +606,14 @@ void dmDevPrivReset(void) /*************************************************************************************************/ void DmDevPrivInit(void) { + WsfTaskLock(); + dmFcnIfTbl[DM_ID_DEV_PRIV] = (dmFcnIf_t *) &dmDevPrivFcnIf; /* initialize set advertising set random address callback */ dmDevCb.advSetRandAddrCback = NULL; + + WsfTaskUnlock(); } /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_iso.c new file mode 100644 index 00000000000..22edbf858f3 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_iso.c @@ -0,0 +1,889 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief DM Isochronous (ISO) data path management. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include +#include "wsf_types.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "wsf_msg.h" +#include "util/bstream.h" +#include "dm_api.h" +#include "dm_main.h" +#include "dm_conn.h" +#include "dm_cis.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! Column position of next state */ +#define DM_ISO_NEXT_STATE 0 + +/*! Column position of action */ +#define DM_ISO_ACTION 1 + +/*! Number of columns in the state machine state tables */ +#define DM_ISO_NUM_COLS 2 + +/*! Number of data path directions */ +#define DM_ISO_NUM_DIR 2 + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! DM ISO event handler messages for state machine */ +enum +{ + /* messages from API */ + DM_ISO_MSG_API_SETUP = DM_MSG_START(DM_ID_ISO), /*!< Setup ISO Data Path */ + DM_ISO_MSG_API_REMOVE, /*!< Remove ISO Data Path */ + + /* messages from HCI */ + DM_ISO_MSG_HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL, /*!< HCI LE Set ISO Data Path Command Complete Failure Event */ + DM_ISO_MSG_HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL, /*!< HCI LE Set ISO Data Path Command Complete Event */ + DM_ISO_MSG_HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL, /*!< HCI LE Remove ISO Data Path Command Complete Failure Event */ + DM_ISO_MSG_HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL /*!< HCI LE Remove ISO Data Path Command Complete Event */ +}; + +/* Number of ISO messages */ +#define DM_ISO_NUM_MSGS (DM_ISO_MSG_HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL - DM_ISO_MSG_API_SETUP + 1) + +/*! CIS CIG state machine actions */ +enum +{ + DM_ISO_SM_ACT_NONE, /*!< No Action */ + DM_ISO_SM_ACT_SETUP, /*!< Process Setup */ + DM_ISO_SM_ACT_SETUP_SUCCESS, /*!< Process Setup Successful */ + DM_ISO_SM_ACT_SETUP_FAILED, /*!< Process Setup Failed */ + DM_ISO_SM_ACT_REMOVE, /*!< Process Remove */ + DM_ISO_SM_ACT_REMOVED, /*!< Process Removed */ + DM_ISO_SM_ACT_REMOVE_FAILED, /*!< Process Remove Failed */ +}; + +/*! CIS CIG state machine states */ +enum +{ + DM_ISO_SM_ST_IDLE, /*!< Idle State */ + DM_ISO_SM_ST_CONFIGING, /*!< Configuring State */ + DM_ISO_SM_ST_CONFIGED, /*!< Configured State */ + DM_ISO_SM_ST_REMOVING, /*!< Removing State */ + + DM_ISO_SM_NUM_STATES +}; + +/* Data structure for DM_ISO_MSG_API_SETUP */ +typedef struct +{ + wsfMsgHdr_t hdr; + HciIsoSetupDataPath_t dataPathParam; +} dmIsoApiSetup_t; + +/* Data structure for DM_ISO_MSG_API_REMOVE */ +typedef struct +{ + wsfMsgHdr_t hdr; + uint8_t directionBits; +} dmIsoApiRemove_t; + +/*! Union of all DM ISO state machine messages */ +typedef union +{ + wsfMsgHdr_t hdr; + + /* API messages */ + dmIsoApiSetup_t apiSetup; + dmIsoApiRemove_t apiRemove; + + /* HCI LE events */ + hciLeSetupIsoDataPathCmdCmplEvt_t hciLeSetupIsoDataPathCmdCmpl; + hciLeRemoveIsoDataPathCmdCmplEvt_t hciLeRemoveIsoDataPathCmdCmpl; +} dmIsoMsg_t; + +/*! ISO connection control block */ +typedef struct +{ + uint16_t handle; /*!< Connection handle of CIS or BIS. */ + uint8_t state[DM_ISO_NUM_DIR];/*!< Main state for each direction. */ + bool_t rmReqEvtSent; /*!< TRUE if remove data path request or event been sent. */ + uint8_t inUse; /*!< TRUE if entry in use. */ +} dmIsoCb_t; + +/*! Action functions */ +typedef void (*dmIsoAct_t)(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void dmIsoReset(void); +static void dmIsoMsgHandler(wsfMsgHdr_t *pMsg); +static void dmIsoHciHandler(hciEvt_t *pEvent); + +static void dmIsoSmActNone(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActSetup(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActSetupSuccess(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActSetupFailed(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActRemove(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActRemoved(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); +static void dmIsoSmActRemoveFailed(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState); + +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! DM ISO state machine state tables */ +static const uint8_t dmIsoStateTbl[DM_ISO_SM_NUM_STATES][DM_ISO_NUM_MSGS][DM_ISO_NUM_COLS] = +{ + /* Idle state */ + { + /* Event Next state Action */ + /* API_SETUP */ {DM_ISO_SM_ST_CONFIGING, DM_ISO_SM_ACT_SETUP}, + /* API_REMOVE */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP_SUCCESS}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_NONE} + }, + /* Configuring state */ + { + /* Event Next state Action */ + /* API_SETUP */ {DM_ISO_SM_ST_CONFIGING, DM_ISO_SM_ACT_NONE}, + /* API_REMOVE */ {DM_ISO_SM_ST_CONFIGING, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_SETUP_FAILED}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP_SUCCESS}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_CONFIGING, DM_CIS_SM_ACT_NONE}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_SETUP_FAILED} + }, + /* Configured state */ + { + /* Event Next state Action */ + /* API_SETUP */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP}, + /* API_REMOVE */ {DM_ISO_SM_ST_REMOVING, DM_ISO_SM_ACT_REMOVE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP_FAILED}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP_SUCCESS}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_SETUP_FAILED}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_REMOVED} + }, + /* Removing state */ + { + /* Event Next state Action */ + /* API_SETUP */ {DM_ISO_SM_ST_REMOVING, DM_ISO_SM_ACT_NONE}, + /* API_REMOVE */ {DM_ISO_SM_ST_REMOVING, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_REMOVING, DM_ISO_SM_ACT_NONE}, + /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_REMOVING, DM_ISO_SM_ACT_REMOVE}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL */ {DM_ISO_SM_ST_CONFIGED, DM_ISO_SM_ACT_REMOVE_FAILED}, + /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL */ {DM_ISO_SM_ST_IDLE, DM_ISO_SM_ACT_REMOVED} + } +}; + +/*! DM ISO action function table */ +static const dmIsoAct_t dmIsoAct[] = +{ + dmIsoSmActNone, + dmIsoSmActSetup, + dmIsoSmActSetupSuccess, + dmIsoSmActSetupFailed, + dmIsoSmActRemove, + dmIsoSmActRemoved, + dmIsoSmActRemoveFailed +}; + +/* ISO component function interface */ +static const dmFcnIf_t dmIsoFcnIf = +{ + dmIsoReset, + dmIsoHciHandler, + dmIsoMsgHandler +}; + +/*! DM ISO control block */ +static dmIsoCb_t dmIsoCb[DM_ISO_DATA_PATH_MAX]; + +/*************************************************************************************************/ +/*! + * \brief Allocate a DM ISO control block. + * + * \param handle Connection handle of CIS or BIS. + * + * \return Pointer to ISO control block or NULL if failure. + */ +/*************************************************************************************************/ +dmIsoCb_t *dmIsoCbAlloc(uint16_t handle) +{ + dmIsoCb_t *pIsoCb = dmIsoCb; + uint8_t i; + + for (i = 0; i < DM_ISO_DATA_PATH_MAX; i++, pIsoCb++) + { + if (pIsoCb->inUse == FALSE) + { + memset(pIsoCb, 0, sizeof(dmIsoCb_t)); + + pIsoCb->handle = handle; + pIsoCb->inUse = TRUE; + + DM_TRACE_ALLOC1("dmIsoCbAlloc %d", handle); + + return pIsoCb; + } + } + + DM_TRACE_ERR0("dmIsoCbAlloc failed"); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Deallocate a DM ISO control block. + * + * \param pIsoCb ISO control block. + * + * \return None. + */ +/*************************************************************************************************/ +void dmIsoCbDealloc(dmIsoCb_t *pIsoCb) +{ + DM_TRACE_FREE1("dmIsoCbDealloc %d", pIsoCb->handle); + + pIsoCb->inUse = FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Find a ISO data path control block with matching handle. + * + * \param handle Connection handle of CIS or BIS. + * + * \return Pointer to ISO control block. NULL if not found. + */ +/*************************************************************************************************/ +dmIsoCb_t *dmIsoCbByHandle(uint16_t handle) +{ + dmIsoCb_t *pIsoCb = dmIsoCb; + uint8_t i; + + for (i = DM_ISO_DATA_PATH_MAX; i > 0; i--, pIsoCb++) + { + if (pIsoCb->inUse && (pIsoCb->handle == handle)) + { + return pIsoCb; + } + } + + DM_TRACE_WARN1("dmIsoCcbByHandle not found %d", handle); + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Empty action. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActNone(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Setup ISO data path for the given connection handle. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActSetup(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + dmIsoApiSetup_t *pSetup = &pMsg->apiSetup; + + /* if connection handle is for CIS, BIS or BIS Sync */ + if (DmCisConnInUse(pIsoCb->handle) || DmBisInUse(pIsoCb->handle) || DmBisSyncInUse(pIsoCb->handle)) + { + /* setup ISO data path */ + HciLeSetupIsoDataPathCmd(&pSetup->dataPathParam); + } + else + { + DM_TRACE_WARN1("dmIsoSmActSetup: connection handle (%d) isn't for CIS or BIS", pIsoCb->handle); + + pMsg->hdr.status = HCI_ERR_UNKNOWN_HANDLE; + + /* restore old state */ + pIsoCb->state[pSetup->dataPathParam.dpDir] = oldState; + + /* notify app about failure */ + dmIsoSmActSetupFailed(pIsoCb, pMsg, oldState); + } +} + +/*************************************************************************************************/ +/*! + * \brief Handle a ISO data path setup successful event from HCI. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActSetupSuccess(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + pMsg->hdr.event = DM_ISO_DATA_PATH_SETUP_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Handle a ISO data path setup failure event from HCI. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActSetupFailed(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + /* if both data path directions in idle state */ + if ((pIsoCb->state[HCI_ISO_DATA_DIR_INPUT] == DM_ISO_SM_ST_IDLE) && + (pIsoCb->state[HCI_ISO_DATA_DIR_OUTPUT] == DM_ISO_SM_ST_IDLE)) + { + dmIsoCbDealloc(pIsoCb); + } + + pMsg->hdr.event = DM_ISO_DATA_PATH_SETUP_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Remove ISO data path for the given connection handle. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActRemove(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + dmIsoApiRemove_t *pRemove = &pMsg->apiRemove; + + /* if remove data path request hasn't been sent down for this handle */ + if (pIsoCb->rmReqEvtSent == FALSE) + { + /* remove ISO data path */ + HciLeRemoveIsoDataPathCmd(pMsg->hdr.param, pRemove->directionBits); + + /* in case if both data path directions are being removed together */ + pIsoCb->rmReqEvtSent = TRUE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Handle a ISO data path removed event from HCI. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActRemoved(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + /* if remove data path event hasn't been sent up for this handle */ + if (pIsoCb->rmReqEvtSent == FALSE) + { + uint8_t event = pMsg->hdr.event; + + pMsg->hdr.event = DM_ISO_DATA_PATH_REMOVE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); + + /* in case if both data path directions are being removed with single command */ + pMsg->hdr.event = event; + pIsoCb->rmReqEvtSent = TRUE; + } + + /* if both data path directions in idle state */ + if ((pIsoCb->state[HCI_ISO_DATA_DIR_INPUT] == DM_ISO_SM_ST_IDLE) && + (pIsoCb->state[HCI_ISO_DATA_DIR_OUTPUT] == DM_ISO_SM_ST_IDLE)) + { + dmIsoCbDealloc(pIsoCb); + } +} + +/*************************************************************************************************/ +/*! + * \brief Handle a ISO data path remove failure event from HCI. + * + * \param pIsoCb CIG control block. + * \param pMsg WSF message. + * \param oldState Old state. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoSmActRemoveFailed(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t oldState) +{ + pMsg->hdr.event = DM_ISO_DATA_PATH_REMOVE_IND; + (*dmCb.cback)((dmEvt_t *) pMsg); +} + +/*************************************************************************************************/ +/*! + * \brief Execute the DM ISO state machine. + * + * \param pIsoCb ISO control block. + * \param pMsg WSF message. + * \param direction Data path direction. + * + * \return None. + */ +/*************************************************************************************************/ +void dmIsoSmExecute(dmIsoCb_t *pIsoCb, dmIsoMsg_t *pMsg, uint8_t direction) +{ + uint8_t action; + uint8_t event; + uint8_t state = pIsoCb->state[direction]; + + DM_TRACE_INFO2("dmIsoSmExecute event=%d state=%d", pMsg->hdr.event, state); + + /* get the event */ + event = DM_MSG_MASK(pMsg->hdr.event); + + /* get action */ + action = dmIsoStateTbl[state][event][DM_ISO_ACTION]; + + /* set next state */ + pIsoCb->state[direction] = dmIsoStateTbl[state][event][DM_ISO_NEXT_STATE]; + + /* execute action function */ + (*dmIsoAct[action])(pIsoCb, pMsg, state); +} + +/*************************************************************************************************/ +/*! + * \brief Reset the OSI module. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoReset(void) +{ + dmIsoCb_t *pIsoCb = dmIsoCb; + uint8_t i; + + for (i = 0; i < DM_ISO_DATA_PATH_MAX; i++, pIsoCb++) + { + if (pIsoCb->inUse) + { + dmIsoCbDealloc(pIsoCb); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM ISO WSF message handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoMsgHandler(wsfMsgHdr_t *pMsg) +{ + dmIsoCb_t *pIsoCb; + + /* look up cb from handle */ + if ((pIsoCb = dmIsoCbByHandle(pMsg->param)) != NULL) + { + if (pMsg->event == DM_ISO_MSG_API_SETUP) + { + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pMsg, ((dmIsoApiSetup_t *) pMsg)->dataPathParam.dpDir); + } + else /* DM_ISO_MSG_API_REMOVE */ + { + uint8_t directionBits = ((dmIsoApiRemove_t *) pMsg)->directionBits; + + /* in case if both data path directions are being removed with single command */ + pIsoCb->rmReqEvtSent = FALSE; + + /* if input direction being removed */ + if (directionBits & HCI_ISO_DATA_PATH_INPUT_BIT) + { + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pMsg, HCI_ISO_DATA_DIR_INPUT); + } + + /* if output direction being removed */ + if (directionBits & HCI_ISO_DATA_PATH_OUTPUT_BIT) + { + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pMsg, HCI_ISO_DATA_DIR_OUTPUT); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM ISO data path HCI callback event handler. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoDpHciHandler(hciEvt_t *pEvent) +{ + dmIsoCb_t *pIsoCb; + + /* look up cb from handle */ + if ((pIsoCb = dmIsoCbByHandle(pEvent->hdr.param)) != NULL) + { + /* translate HCI event to state machine event */ + if (pEvent->hdr.event == HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT) + { + uint8_t direction; + + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_ISO_MSG_HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL; + } + else + { + pEvent->hdr.event = DM_ISO_MSG_HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_FAIL; + } + + /* find out direction being set up */ + if (pIsoCb->state[HCI_ISO_DATA_DIR_INPUT] == DM_ISO_SM_ST_CONFIGING) + { + direction = HCI_ISO_DATA_DIR_INPUT; + } + else + { + direction = HCI_ISO_DATA_DIR_OUTPUT; + } + + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pEvent, direction); + } + else /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT */ + { + if (pEvent->hdr.status == HCI_SUCCESS) + { + pEvent->hdr.event = DM_ISO_MSG_HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL; + } + else + { + pEvent->hdr.event = DM_ISO_MSG_HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_FAIL; + } + + /* in case if both data path directions are being removed with single command */ + pIsoCb->rmReqEvtSent = FALSE; + + /* if input direction being removed */ + if (pIsoCb->state[HCI_ISO_DATA_DIR_INPUT] == DM_ISO_SM_ST_REMOVING) + { + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pEvent, HCI_ISO_DATA_DIR_INPUT); + } + + /* if output direction being removed */ + if (pIsoCb->state[HCI_ISO_DATA_DIR_OUTPUT] == DM_ISO_SM_ST_REMOVING) + { + /* execute state machine */ + dmIsoSmExecute(pIsoCb, (dmIsoMsg_t *) pEvent, HCI_ISO_DATA_DIR_OUTPUT); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief DM ISO HCI callback event handler. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoHciHandler(hciEvt_t *pEvent) +{ + /* if ISO data path event */ + if ((pEvent->hdr.event == HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT) || + (pEvent->hdr.event == HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT)) + { + dmIsoDpHciHandler(pEvent); + } + else + { + /* handle incoming event */ + switch (pEvent->hdr.event) + { + case HCI_CONFIG_DATA_PATH_CMD_CMPL_CBACK_EVT: + pEvent->hdr.event = DM_DATA_PATH_CONFIG_IND; + break; + + case HCI_READ_LOCAL_SUP_CODECS_CMD_CMPL_CBACK_EVT: + pEvent->hdr.event = DM_READ_LOCAL_SUP_CODECS_IND; + break; + + case HCI_READ_LOCAL_SUP_CODEC_CAP_CMD_CMPL_CBACK_EVT: + pEvent->hdr.event = DM_READ_LOCAL_SUP_CODEC_CAP_IND; + break; + + case HCI_READ_LOCAL_SUP_CTR_DLY_CMD_CMPL_CBACK_EVT: + pEvent->hdr.event = DM_READ_LOCAL_SUP_CTR_DLY_IND; + break; + + default: + /* should never get here */ + return; + } + + (*dmCb.cback)((dmEvt_t *) pEvent); + } +} + +/*************************************************************************************************/ +/*! + * \brief HCI ISO data callback function. + * + * \param pPacket A buffer containing an ISO packet. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoHciIsoCback(uint8_t *pPacket) +{ + uint16_t handle; + uint16_t hciLen; + uint8_t *p = pPacket; + + /* parse HCI handle and length */ + BSTREAM_TO_UINT16(handle, p); + handle &= HCI_HANDLE_MASK; + BSTREAM_TO_UINT16(hciLen, p); + + /* if connection handle is for BIS Sync */ + if (DmBisSyncInUse(handle)) + { + /* if insufficient security for Broadcast_Code */ + if (DmBigSyncGetSecLevel(handle) > DM_SEC_LEVEL_BCAST_NONE) + { + DM_TRACE_INFO2("dmIsoHciIsoCback: BIS packet of length %u dropped for handle = %u", hciLen, handle); + } + } + + /* deallocate buffer */ + WsfMsgFree(pPacket); +} + +/*************************************************************************************************/ +/*! + * \brief HCI flow control callback function. + * + * \param handle The connection handle. + * \param flowDisabled TRUE if data flow is disabled. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmIsoHciFlowCback(uint16_t handle, bool_t flowDisabled) +{ + DM_TRACE_INFO2("flowDisabled=%u handle=%u", flowDisabled, handle); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize DM ISO manager. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoInit(void) +{ + WsfTaskLock(); + + dmFcnIfTbl[DM_ID_ISO] = (dmFcnIf_t *) &dmIsoFcnIf; + + /* Register with HCI */ + HciIsoRegister(dmIsoHciIsoCback, dmIsoHciFlowCback); + + WsfTaskUnlock(); +} + +/*************************************************************************************************/ +/*! + * \brief Setup the isochronous data path between the Host and the Controller for an established + * CIS or BIS identified by the connection handle parameter. + * + * \param pDataPathParam Parameters to setup ISO data path. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoDataPathSetup(HciIsoSetupDataPath_t *pDataPathParam) +{ + dmIsoCb_t *pIsoCb = NULL; + uint16_t handle = pDataPathParam->handle; + dmIsoApiSetup_t *pMsg; + + WSF_ASSERT(pDataPathParam->dpDir < DM_ISO_NUM_DIR) + + /* make sure ISO cb not already allocated */ + WsfTaskLock(); + if ((pIsoCb = dmIsoCbByHandle(handle)) == NULL) + { + /* allocate Cig cb */ + pIsoCb = dmIsoCbAlloc(handle); + } + WsfTaskUnlock(); + + if (pIsoCb != NULL) + { + if ((pMsg = WsfMsgAlloc(sizeof(dmIsoApiSetup_t) + pDataPathParam->codecConfigLen)) != NULL) + { + pMsg->hdr.event = DM_ISO_MSG_API_SETUP; + pMsg->hdr.param = handle; + + memcpy(&pMsg->dataPathParam, pDataPathParam, sizeof(HciIsoSetupDataPath_t)); + + if (pDataPathParam->codecConfigLen > 0) + { + pMsg->dataPathParam.pCodecConfig = (uint8_t *)(pMsg + 1); + memcpy(pMsg->dataPathParam.pCodecConfig, pDataPathParam->pCodecConfig, pDataPathParam->codecConfigLen); + } + else + { + pMsg->dataPathParam.pCodecConfig = NULL; + } + + WsfMsgSend(dmCb.handlerId, pMsg); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Remove the input and/or output data path(s) associated with a CIS or BIS identified + * by the connection handle parameter. + * + * \param handle Connection handle of CIS or BIS. + * \param directionBits Data path direction bits. + * + * \return None. + */ +/*************************************************************************************************/ +void DmIsoDataPathRemove(uint16_t handle, uint8_t directionBits) +{ + dmIsoApiRemove_t *pMsg; + + WSF_ASSERT((directionBits & HCI_ISO_DATA_PATH_INPUT_BIT) || (directionBits & HCI_ISO_DATA_PATH_OUTPUT_BIT)) + + if ((pMsg = WsfMsgAlloc(sizeof(dmIsoApiRemove_t))) != NULL) + { + pMsg->hdr.event = DM_ISO_MSG_API_REMOVE; + pMsg->hdr.param = handle; + pMsg->directionBits = directionBits; + + WsfMsgSend(dmCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Request the Controller to configure the data transport path in a given direction + * between the Controller and the Host. + * + * \param pDataPathParam Parameters for configuring data path. + * + * \return None. + */ +/*************************************************************************************************/ +void DmDataPathConfig(HciConfigDataPath_t *pDataPathParam) +{ + HciConfigDataPathCmd(pDataPathParam); +} + +/*************************************************************************************************/ +/*! + * \brief Read a list of the codecs supported by the Controller, as well as vendor specific + * codecs, which are defined by an individual manufacturer. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCodecs(void) +{ + HciReadLocalSupCodecsCmd(); +} + +/*************************************************************************************************/ +/*! + * \brief Read a list of codec capabilities supported by the Controller for a given codec. + * + * \param pCodecParam Parameters for reading local supported codec capabilities. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCodecCap(HciReadLocalSupCodecCaps_t *pCodecParam) +{ + HciReadLocalSupCodecCapCmd(pCodecParam); +} + +/*************************************************************************************************/ +/*! + * \brief Read the range of supported Controller delays for the codec specified by Codec ID on + * a given transport type specified by Logical Transport Type, in the direction specified + * by Direction, and with the codec configuration specified by Codec Configuration. + * + * \param pDelayParam Parameters for reading local supported controller delay. + * + * \return None. + */ +/*************************************************************************************************/ +void DmReadLocalSupCtrDly(HciReadLocalSupControllerDly_t *pDelayParam) +{ + HciReadLocalSupControllerDlyCmd(pDelayParam); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c index ede1811d871..90116478d88 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager main module. + * \file + * + * \brief Device manager main module. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -106,13 +108,26 @@ static const uint8_t dmHciToIdTbl[] = DM_ID_CONN_CTE, /* HCI_LE_SET_CONN_CTE_TX_PARAMS_CMD_CMPL_CBACK_EVT */ DM_ID_CONN_CTE, /* HCI_LE_CONN_CTE_REQ_ENABLE_CMD_CMPL_CBACK_EVT */ DM_ID_CONN_CTE, /* HCI_LE_CONN_CTE_RSP_ENABLE_CMD_CMPL_CBACK_EVT */ - DM_ID_CONN_CTE /* HCI_LE_READ_ANTENNA_INFO_CMD_CMPL_CBACK_EVT */ + DM_ID_CONN_CTE, /* HCI_LE_READ_ANTENNA_INFO_CMD_CMPL_CBACK_EVT */ + DM_ID_CIS, /* HCI_LE_CIS_EST_CBACK_EVT */ + DM_ID_CIS, /* HCI_LE_CIS_REQ_CBACK_EVT */ + DM_ID_CIS, /* HCI_CIS_DISCONNECT_CMPL_CBACK_EVT */ + DM_ID_CONN_2, /* HCI_LE_REQ_PEER_SCA_CBACK_EVT */ + DM_ID_CIS_CIG, /* HCI_LE_SET_CIG_PARAMS_CMD_CMPL_CBACK_EVT */ + DM_ID_CIS_CIG, /* HCI_LE_REMOVE_CIG_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_LE_SETUP_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_LE_REMOVE_ISO_DATA_PATH_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_CONFIG_DATA_PATH_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_READ_LOCAL_SUP_CODECS_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_READ_LOCAL_SUP_CODEC_CAP_CMD_CMPL_CBACK_EVT */ + DM_ID_ISO, /* HCI_READ_LOCAL_SUP_CTR_DLY_CMD_CMPL_CBACK_EVT */ + DM_ID_BIS, /* HCI_LE_CREATE_BIG_CMPL_CBACK_EVT */ + DM_ID_BIS, /* HCI_LE_TERM_BIG_CMPL_CBACK_EVT */ + DM_ID_BIS_SYNC, /* HCI_LE_BIG_SYNC_EST_CBACK_EVT */ + DM_ID_BIS_SYNC, /* HCI_LE_BIG_SYNC_LOST_CBACK_EVT */ + DM_ID_BIS_SYNC, /* HCI_LE_BIG_TERM_SYNC_CMPL_CBACK_EVT */ + DM_ID_BIS_SYNC /* HCI_LE_BIG_INFO_ADV_REPORT_CBACK_EVT */ #if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS - /* these 3 were inexplicably missing */ - , DM_ID_DEV /* HCI_CIS_EST_CBACK_EVT */ - , DM_ID_DEV /* HCI_CIS_REQ_CBACK_EVT */ - , DM_ID_DEV /* HCI_REQ_PEER_SCA_CBACK_EVT */ - , DM_ID_DEV /* HCI_UNHANDLED_CMD_COMPL_CBACK_EVT */ #endif }; @@ -187,6 +202,25 @@ static const uint16_t dmEvtCbackLen[] = sizeof(hciLeConnCteRspEnableCmdCmplEvt_t), /* DM_CONN_CTE_RSP_START_IND */ sizeof(hciLeConnCteRspEnableCmdCmplEvt_t), /* DM_CONN_CTE_RSP_STOP_IND */ sizeof(hciLeReadAntennaInfoCmdCmplEvt_t), /* DM_READ_ANTENNA_INFO_IND */ + sizeof(hciLeSetCigParamsCmdCmplEvt_t), /* DM_CIS_CIG_CONFIG_IND */ + sizeof(hciLeRemoveCigCmdCmplEvt_t), /* DM_CIS_CIG_REMOVE_IND */ + sizeof(HciLeCisReqEvt_t), /* DM_CIS_REQ_IND */ + sizeof(HciLeCisEstEvt_t), /* DM_CIS_OPEN_IND */ + sizeof(hciDisconnectCmplEvt_t), /* DM_CIS_CLOSE_IND */ + sizeof(HciLeReqPeerScaCmplEvt_t_t), /* DM_REQ_PEER_SCA_IND */ + sizeof(hciLeSetupIsoDataPathCmdCmplEvt_t), /* DM_ISO_DATA_PATH_SETUP_IND */ + sizeof(hciLeRemoveIsoDataPathCmdCmplEvt_t), /* DM_ISO_DATA_PATH_REMOVE_IND */ + sizeof(hciConfigDataPathCmdCmplEvt_t), /* DM_DATA_PATH_CONFIG_IND */ + sizeof(hciReadLocalSupCodecsCmdCmplEvt_t), /* DM_READ_LOCAL_SUP_CODECS_IND */ + sizeof(hciReadLocalSupCodecCapCmdCmplEvt_t), /* DM_READ_LOCAL_SUP_CODEC_CAP_IND */ + sizeof(hciReadLocalSupCtrDlyCmdCmplEvt_t), /* DM_READ_LOCAL_SUP_CTR_DLY_IND */ + sizeof(HciLeCreateBigCmplEvt_t), /* DM_BIG_START_IND */ + sizeof(HciLeTerminateBigCmplEvt_t), /* DM_BIG_STOP_IND */ + sizeof(HciLeBigSyncEstEvt_t), /* DM_BIG_SYNC_EST_IND */ + sizeof(HciLeBigSyncEstEvt_t), /* DM_BIG_SYNC_EST_FAIL_IND */ + sizeof(HciLeBigSyncLostEvt_t), /* DM_BIG_SYNC_LOST_IND */ + sizeof(HciLeBigTermSyncCmplEvt_t), /* DM_BIG_SYNC_STOP_IND */ + sizeof(HciLeBigInfoAdvRptEvt_t), /* DM_BIG_INFO_ADV_REPORT_IND */ sizeof(dmL2cCmdRejEvt_t), /* DM_L2C_CMD_REJ_IND */ sizeof(wsfMsgHdr_t), /* DM_ERROR_IND */ sizeof(hciHwErrorEvt_t), /* DM_HW_ERROR_IND */ @@ -221,7 +255,14 @@ dmFcnIf_t *dmFcnIfTbl[DM_NUM_IDS] = (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_ADV_PER */ (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_SYNC */ (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_PAST */ - (dmFcnIf_t *) &dmFcnDefault /* DM_ID_CONN_CTE */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_CONN_CTE */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_CONN_UPD */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_PRIV_AES */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_CIS */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_CIS_CIG */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_BIS */ + (dmFcnIf_t *) &dmFcnDefault, /* DM_ID_BIS_SYNC */ + (dmFcnIf_t *) &dmFcnDefault /* DM_ID_ISO */ }; /* Control block */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.h index 979c3773f90..723b0610f6c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_MAIN_H @@ -48,16 +50,23 @@ extern "C" { #define DM_ID_SYNC 11 #define DM_ID_PAST 12 #define DM_ID_CONN_CTE 13 -#define DM_NUM_IDS 14 +#define DM_ID_CONN_UPD 14 +#define DM_ID_PRIV_AES 15 +#define DM_ID_CIS 16 +#define DM_ID_CIS_CIG 17 +#define DM_ID_BIS 18 +#define DM_ID_BIS_SYNC 19 +#define DM_ID_ISO 20 +#define DM_NUM_IDS 21 /* Start of component message enumeration */ -#define DM_MSG_START(id) ((id) << 4) +#define DM_MSG_START(id) ((id) << 3) /* Get the component ID from a message ID */ -#define DM_ID_FROM_MSG(msg) ((msg) >> 4) +#define DM_ID_FROM_MSG(msg) ((msg) >> 3) /* Mask off the ID from the message ID */ -#define DM_MSG_MASK(msg) ((msg) & 0x0F) +#define DM_MSG_MASK(msg) ((msg) & 0x07) /* Length of hash part of private resolvable address */ #define DM_PRIV_HASH_LEN 3 diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_past.c index 0a48145cdd0..983e293cbae 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_past.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager periodic advertising sync transfer (PAST) module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager periodic advertising sync transfer (PAST) module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -78,8 +80,14 @@ static const dmFcnIf_t dmPastFcnIf = /*************************************************************************************************/ void DmPastInit(void) { + WsfTaskLock(); + /* set function interface table */ dmFcnIfTbl[DM_ID_PAST] = (dmFcnIf_t *) &dmPastFcnIf; + + HciSetLeSupFeat((HCI_LE_SUP_FEAT_RECV_CTE | HCI_LE_SUP_FEAT_PAST_SENDER | HCI_LE_SUP_FEAT_PAST_RECIPIENT), TRUE); + + WsfTaskUnlock(); } /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.c index e27fbeaafa4..50124b4c638 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM PHY module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM PHY module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -237,5 +239,11 @@ void DmSetPhy(dmConnId_t connId, uint8_t allPhys, uint8_t txPhys, uint8_t rxPhys /*************************************************************************************************/ void DmPhyInit(void) { + WsfTaskLock(); + dmFcnIfTbl[DM_ID_PHY] = (dmFcnIf_t *) &dmPhyFcnIf; + + HciSetLeSupFeat((HCI_LE_SUP_FEAT_LE_2M_PHY | HCI_LE_SUP_FEAT_LE_CODED_PHY), TRUE); + + WsfTaskUnlock(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.h index 4b9cdf44168..9f7fcecf67e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_phy.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM PHY module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM PHY module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_PHY_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.c index 16177f6f8dd..45966dc6bfc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager privacy module. + * \file + * + * \brief Device manager privacy module. + * + * Copyright (c) 2011-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,21 +44,19 @@ Local Variables **************************************************************************************************/ -/* action function table */ +/* Privacy action function table */ static const dmPrivAct_t dmPrivAct[] = { dmPrivActResolveAddr, - dmPrivActResAddrAesCmpl, dmPrivActAddDevToResList, dmPrivActRemDevFromResList, dmPrivActClearResList, dmPrivActSetAddrResEnable, dmPrivActSetPrivacyMode, - dmPrivActGenAddr, - dmPrivActGenAddrAesCmpl + dmPrivActGenAddr }; -/* Component function interface */ +/* Privacy component function interface */ static const dmFcnIf_t dmPrivFcnIf = { dmPrivReset, @@ -64,6 +64,21 @@ static const dmFcnIf_t dmPrivFcnIf = dmPrivMsgHandler }; +/* Privacy AES action function table */ +static const dmPrivAct_t dmPrivAesAct[] = +{ + dmPrivAesActResAddrAesCmpl, + dmPrivAesActGenAddrAesCmpl +}; + +/* Privacy AES component function interface */ +static const dmFcnIf_t dmPrivAesFcnIf = +{ + dmEmptyReset, + (dmHciHandler_t) dmEmptyHandler, + dmPrivAesMsgHandler +}; + /* Control block */ dmPrivCb_t dmPrivCb; @@ -121,7 +136,7 @@ void dmPrivActResolveAddr(dmPrivMsg_t *pMsg) * \return None. */ /*************************************************************************************************/ -void dmPrivActResAddrAesCmpl(dmPrivMsg_t *pMsg) +void dmPrivAesActResAddrAesCmpl(dmPrivMsg_t *pMsg) { /* compare calculated value with hash */ if (memcmp(dmPrivCb.hash, pMsg->aes.pCiphertext, DM_PRIV_HASH_LEN) == 0) @@ -280,7 +295,7 @@ void dmPrivActGenAddr(dmPrivMsg_t *pMsg) * \return None. */ /*************************************************************************************************/ -void dmPrivActGenAddrAesCmpl(dmPrivMsg_t *pMsg) +void dmPrivAesActGenAddrAesCmpl(dmPrivMsg_t *pMsg) { dmPrivGenAddrIndEvt_t *pAddrEvt = (dmPrivGenAddrIndEvt_t*) pMsg; @@ -420,6 +435,21 @@ void dmPrivReset(void) dmCb.llPrivEnabled = FALSE; } +/*************************************************************************************************/ +/*! + * \brief DM priv AES event handler. + * + * \param pMsg WSF message. + * + * \return None. + */ +/*************************************************************************************************/ +void dmPrivAesMsgHandler(wsfMsgHdr_t *pMsg) +{ + /* execute action function */ + (*dmPrivAesAct[DM_MSG_MASK(pMsg->event)])((dmPrivMsg_t *) pMsg); +} + /*************************************************************************************************/ /*! * \brief Initialize DM privacy module. @@ -429,7 +459,12 @@ void dmPrivReset(void) /*************************************************************************************************/ void DmPrivInit(void) { + WsfTaskLock(); + dmFcnIfTbl[DM_ID_PRIV] = (dmFcnIf_t *) &dmPrivFcnIf; + dmFcnIfTbl[DM_ID_PRIV_AES] = (dmFcnIf_t *) &dmPrivAesFcnIf; + + WsfTaskUnlock(); } /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.h index ff247c9a538..97cb6448a77 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_priv.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM privacy module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM privacy module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_PRIV_H @@ -37,17 +39,22 @@ extern "C" { Macros **************************************************************************************************/ -/* DM priv event handler messages */ +/* DM privacy event handler messages */ enum { DM_PRIV_MSG_API_RESOLVE_ADDR = DM_MSG_START(DM_ID_PRIV), - DM_PRIV_MSG_RESOLVE_AES_CMPL, DM_PRIV_MSG_API_ADD_DEV_TO_RES_LIST, DM_PRIV_MSG_API_REM_DEV_FROM_RES_LIST, DM_PRIV_MSG_API_CLEAR_RES_LIST, DM_PRIV_MSG_API_SET_ADDR_RES_ENABLE, DM_PRIV_MSG_API_SET_PRIVACY_MODE, - DM_PRIV_MSG_API_GEN_ADDR, + DM_PRIV_MSG_API_GEN_ADDR +}; + +/* DM privacy AES event handler messages */ +enum +{ + DM_PRIV_MSG_RESOLVE_AES_CMPL = DM_MSG_START(DM_ID_PRIV_AES), DM_PRIV_MSG_GEN_ADDR_AES_CMPL }; @@ -105,7 +112,7 @@ typedef struct uint8_t mode; } dmPrivApiSetPrivacyMode_t; -/* Union of all priv messages */ +/* Union of all privacy messages */ typedef union { wsfMsgHdr_t hdr; @@ -138,21 +145,26 @@ typedef struct Function declarations **************************************************************************************************/ -/* component inteface */ +/* Privacy component inteface */ void dmPrivMsgHandler(wsfMsgHdr_t *pMsg); void dmPrivHciHandler(hciEvt_t *pEvent); void dmPrivReset(void); -/* action functions */ +/* Privacy action functions */ void dmPrivActResolveAddr(dmPrivMsg_t *pMsg); -void dmPrivActResAddrAesCmpl(dmPrivMsg_t *pMsg); void dmPrivActAddDevToResList(dmPrivMsg_t *pMsg); void dmPrivActRemDevFromResList(dmPrivMsg_t *pMsg); void dmPrivActSetAddrResEnable(dmPrivMsg_t *pMsg); void dmPrivActClearResList(dmPrivMsg_t *pMsg); void dmPrivActSetPrivacyMode(dmPrivMsg_t *pMsg); void dmPrivActGenAddr(dmPrivMsg_t *pMsg); -void dmPrivActGenAddrAesCmpl(dmPrivMsg_t *pMsg); + +/* Privacy ASE component inteface */ +void dmPrivAesMsgHandler(wsfMsgHdr_t *pMsg); + +/* Privacy ASE action functions */ +void dmPrivAesActResAddrAesCmpl(dmPrivMsg_t *pMsg); +void dmPrivAesActGenAddrAesCmpl(dmPrivMsg_t *pMsg); #ifdef __cplusplus }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.c index f022bd68c4d..1c9d97bee6a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager scan module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager scan module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.h index 468372ee97f..4a42f5ce548 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM scan module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM scan module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_SCAN_H @@ -51,6 +53,9 @@ enum DM_SCAN_STATE_STOPPING }; +/*! Uninitialized HCI sync handle */ +#define DM_SYNC_HCI_HANDLE_NONE 0xFFFF + /************************************************************************************************** Data Types **************************************************************************************************/ @@ -123,7 +128,7 @@ typedef struct wsfTimer_t scanTimer; uint16_t scanInterval[DM_NUM_PHYS]; uint16_t scanWindow[DM_NUM_PHYS]; - bool_t scanState; + uint8_t scanState; uint16_t scanDuration; bool_t filterNextScanRsp; uint8_t discFilter; @@ -137,6 +142,7 @@ typedef struct uint8_t advAddrType; /*!< advertiser address type */ uint16_t handle; /*!< sync handle */ dmSyncId_t syncId; /*!< sync id */ + bool_t encrypt; /*!< Unencrypted or Encrypted */ uint8_t state; /*!< sync state */ uint8_t inUse; /*!< TRUE if entry in use */ } dmSyncCb_t; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_ae.c index 01dc5fc7074..23f898c03c1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_ae.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager extended scan module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager extended scan module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_leg.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_leg.c index 7f67ae91dba..fa953730c31 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_leg.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_scan_leg.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Device manager scan module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Device manager scan module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.c index 4a361659d91..7d66f73b324 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM security module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM security module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.h index 5339347af88..6aa292a70ba 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM security module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM security module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef DM_SEC_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_lesc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_lesc.c index 9e0268e3d20..a8790951d69 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_lesc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_lesc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM security module for LE Secure Connections. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM security module for LE Secure Connections. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_master.c index be8cef81f53..a941ac7e6d4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_master.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM security module for master. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM security module for master. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_slave.c index ab506593751..bb8dd0d6fcf 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sec_slave.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief DM security module for slave. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief DM security module for slave. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sync_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sync_ae.c index 9548a648abc..1f0fb97919f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sync_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_sync_ae.c @@ -1,22 +1,25 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Device manager periodic advertising synchronization management and state machine + * \file + * + * \brief Device manager periodic advertising synchronization management and state machine + * module. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -88,9 +91,6 @@ enum /*! Translate HCI event to state machine message */ #define DM_SYNC_HCI_EVT_2_MSG(evt) (DM_SYNC_MSG_HCI_LE_SYNC_LOST - HCI_LE_PER_ADV_SYNC_LOST_CBACK_EVT + (evt)) -/*! Uninitialized HCI sync handle */ -#define DM_SYNC_HCI_HANDLE_NONE 0xFFFF - /*! Action function */ typedef void (*dmSyncAct_t)(dmSyncCb_t *pCcb, dmSyncMsg_t *pMsg); @@ -762,6 +762,63 @@ void DmSyncStop(dmSyncId_t syncId) } } +/*************************************************************************************************/ +/*! + * \brief Set the encryption mode of the BIG corresponding to the periodic advertising train + * identified by the sync handle. + * + * \param syncHandle Synch handle. + * \param encrypt FALSE (Unencrypted) or FALSE (Encrypted). + * + * \return None. + */ +/*************************************************************************************************/ +void DmSyncSetEncrypt(uint16_t syncHandle, bool_t encrypt) +{ + dmSyncCb_t *pScb; + + if ((pScb = dmSyncCbByHandle(syncHandle)) != NULL) + { + pScb->encrypt = encrypt; + } +} + +/*************************************************************************************************/ +/*! +* \brief Get the encryption mode of the BIG corresponding to the periodic advertising train +* identified by the sync handle. +* +* \param syncHandle Synch handle. +* +* \return TRUE if sync encrypted. FALSE, otherwise. +*/ +/*************************************************************************************************/ +bool_t DmSyncEncrypted(uint16_t syncHandle) +{ + dmSyncCb_t *pScb; + + if ((pScb = dmSyncCbByHandle(syncHandle)) != NULL) + { + return pScb->encrypt; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Get status of sync identified by the handle. + * + * \param syncHandle Synch handle. + * + * \return TRUE if sync is enabled for that handle. FALSE, otherwise. + */ +/*************************************************************************************************/ +bool_t DmSyncEnabled(uint16_t syncHandle) +{ + return (dmSyncCbByHandle(syncHandle) != NULL) ? TRUE : FALSE; +} + /*************************************************************************************************/ /*! * \brief Add device to periodic advertiser list. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.c index 61dd0d3646c..10eadb379ee 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.c @@ -1,22 +1,27 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This is the main module of the HCI subsystem. It contains the API functions for initialization + * and registration. */ /*************************************************************************************************/ @@ -76,6 +81,21 @@ void HciAclRegister(hciAclCback_t aclCback, hciFlowCback_t flowCback) hciCb.flowCback = flowCback; } +/*************************************************************************************************/ +/*! + * \brief Register callbacks for the HCI ISO data path. + * + * \param aclCback ISO data callback function. + * \param flowCback Flow control callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void HciIsoRegister(hciAclCback_t isoCback, hciFlowCback_t flowCback) +{ + hciCb.isoCback = isoCback; + hciCb.isoFlowCback = flowCback; +} /*************************************************************************************************/ /*! diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.h index 936c42d8492..6f4f21c6457 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/hci/hci_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_MAIN_H @@ -69,6 +71,8 @@ typedef struct hciSecCback_t secCback; hciAclCback_t aclCback; hciFlowCback_t flowCback; + hciIsoCback_t isoCback; + hciFlowCback_t isoFlowCback; wsfHandlerId_t handlerId; bool_t resetting; } hciCb_t; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_coc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_coc.c index 7af97f720d8..f78873f1435 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_coc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_coc.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief L2CAP connection oriented channel module. + * \file + * + * \brief L2CAP connection oriented channel module. + * + * Copyright (c) 2014-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -53,9 +55,11 @@ enum L2C_MSG_API_DATA_REQ, L2C_MSG_API_CONNECT_REQ, L2C_MSG_API_DISCONNECT_REQ, + L2C_MSG_API_EN_CONNECT_REQ, + L2C_MSG_API_EN_RECONFIG_REQ, /* messages from timers */ - L2C_MSG_COC_REQ_TIMEOUT + L2C_MSG_COC_REQ_TIMEOUT, }; /************************************************************************************************** @@ -71,7 +75,6 @@ typedef struct uint16_t sduLen; } l2cApiDataReq_t; - /* Data type for L2C_MSG_API_CONNECT_REQ */ typedef struct { @@ -80,12 +83,36 @@ typedef struct uint16_t remotePsm; } l2cApiConnectReq_t; +/* Data type for L2C_MSG_API_EN_CONNECT_REQ */ +typedef struct +{ + wsfMsgHdr_t hdr; + uint16_t psm; + uint16_t credits; + uint16_t handle; + uint8_t numChan; + uint16_t chanList[L2C_MAX_EN_CHAN]; +} l2cApiEnConnectReq_t; + +/* Data type for L2C_MSG_API_EN_RECONFIG_REQ */ +typedef struct +{ + wsfMsgHdr_t hdr; + uint16_t mtu; + uint16_t mps; + uint16_t handle; + uint8_t numChan; + uint16_t chanList[L2C_MAX_EN_CHAN]; +} l2cApiEnReconfigReq_t; + /* Data type for event handler messages */ typedef union { - wsfMsgHdr_t hdr; - l2cApiDataReq_t dataReq; - l2cApiConnectReq_t connectReq; + wsfMsgHdr_t hdr; + l2cApiDataReq_t dataReq; + l2cApiConnectReq_t connectReq; + l2cApiEnConnectReq_t enConnectReq; + l2cApiEnReconfigReq_t enReconfigReq; } l2cCocMsg_t; /* Registration control block */ @@ -93,6 +120,7 @@ typedef struct { l2cCocReg_t reg; /* Registration data structure */ l2cCocCback_t cback; /* Client callback */ + l2cCocAcceptCb_t acceptCback; /* Channel accept callback */ l2cCocRegId_t regId; /* Registration instance ID */ bool_t inUse; /* TRUE if in use */ } l2cRegCb_t; @@ -120,6 +148,8 @@ typedef struct uint16_t psm; uint16_t peerMps; uint16_t peerMtu; + uint16_t pendingMps; + uint16_t pendingMtu; uint16_t peerCredits; uint16_t peerCid; uint16_t localCredits; @@ -146,6 +176,22 @@ typedef struct l2cCocCb_t l2cCocCb; +/*************************************************************************************************/ +/*! + * \brief Default acceptCback. + * + * \param connId DM connection ID. + * \param numChans number of channels requested. + * + * \return number of channels permitted. + */ +/*************************************************************************************************/ +static uint8_t l2cCocAcceptDefaultCb(dmConnId_t connId, uint8_t numChans) +{ + /* Permit all requested channels by default. */ + return numChans; +} + /*************************************************************************************************/ /*! * \brief Allocate a registration control block. @@ -167,6 +213,7 @@ l2cRegCb_t *l2cRegCbAlloc(l2cCocCback_t cback, l2cCocReg_t *pReg) { memcpy(&pCb->reg, pReg, sizeof(l2cCocReg_t)); pCb->cback = cback; + pCb->acceptCback = l2cCocAcceptDefaultCb; pCb->regId = i + 1; pCb->inUse = TRUE; @@ -245,7 +292,7 @@ bool_t l2cCheckPeerCid(dmConnId_t connId, uint16_t peerCid, l2cRegCb_t *pRegCb) (pChanCb->peerCid == peerCid)) { /* peer CID found */ - L2C_TRACE_WARN3("Peer CID in use psm:0x%04x connId:%d peerCid", pRegCb->reg.psm, connId, peerCid); + L2C_TRACE_WARN3("Peer CID in use psm:0x%04x connId:%d peerCid: %d", pRegCb->reg.psm, connId, peerCid); return TRUE; } } @@ -337,6 +384,34 @@ l2cChanCb_t *l2cChanCbAlloc(uint8_t state) return NULL; } +/*************************************************************************************************/ +/*! + * \brief Checks if the given number of channels are free. + * + * \param numChan Number of channels. + * + * \return TRUE if numChan or more channels are free, else FALSE. + */ + /*************************************************************************************************/ +bool_t l2cVerifyFreeChannels(uint8_t numChan) +{ + l2cChanCb_t *pCb = l2cCocCb.chanCb; + uint8_t i; + + for (i = 0; i < L2C_COC_CHAN_MAX; i++, pCb++) + { + if (pCb->state == L2C_CHAN_STATE_UNUSED) + { + if (--numChan == 0) + { + return TRUE; + } + } + } + + return FALSE; +} + /*************************************************************************************************/ /*! * \brief Get a channel control block by ID. @@ -353,6 +428,32 @@ l2cChanCb_t *l2cChanCbByCid(uint16_t cid) return &l2cCocCb.chanCb[cid - L2C_CID_DYN_MIN]; } +/*************************************************************************************************/ +/*! + * \brief Get a channel control block by the peer's channel ID. + * + * \param handle Connection handle. + * \param peerCid Peer channel ID. + * + * \return Pointer to connection control block. + */ +/*************************************************************************************************/ +l2cChanCb_t *l2cChanCbByPeerCid(uint16_t handle, uint16_t peerCid) +{ + l2cChanCb_t *pCb = l2cCocCb.chanCb; + uint8_t i; + + for (i = 0; i < L2C_COC_CHAN_MAX; i++, pCb++) + { + if (pCb->pConnCb && (pCb->pConnCb->handle == handle) && (pCb->peerCid == peerCid)) + { + return pCb; + } + } + + return NULL; +} + /*************************************************************************************************/ /*! * \brief Get a channel control block with matching CID, checking CID range. @@ -397,6 +498,39 @@ l2cChanCb_t *l2cChanCbByCidState(uint16_t cid, uint8_t state) return NULL; } +/*************************************************************************************************/ +/*! + * \brief Get a list of CIDs for the given identifier on the given channel. + * + * \param connId Connection ID. + * \param identifier Identifier value from request. + * \param state Channel state. + * + * \return Array of L2C_MAX_EN_CHAN ptr to l2cChanCb_t (NULL indicates unused). + */ +/*************************************************************************************************/ +l2cChanCb_t **l2cGetChanCbListByIdentifier(dmConnId_t connId, uint8_t identifier, uint8_t state) +{ + static l2cChanCb_t *pList[L2C_MAX_EN_CHAN]; + l2cChanCb_t *pCb = l2cCocCb.chanCb; + uint8_t i; + uint8_t cidPos = 0; + + memset(pList, 0, sizeof(pList)); + + for (i = 0; i < L2C_COC_CHAN_MAX; i++, pCb++) + { + if (pCb->state == state && + pCb->identifier == identifier && + pCb->pConnCb->connId == connId) + { + pList[cidPos++] = pCb; + } + } + + return pList; +} + /*************************************************************************************************/ /*! * \brief Find a matching channel control block in connecting state. @@ -777,6 +911,228 @@ static void l2cSendDisconnectRsp(uint16_t handle, uint16_t identifier, uint16_t } } +/*************************************************************************************************/ +/*! + * \brief Send an enhanced connection request. + * + * \param handle The connection handle. + * \param psm The protocol slave multiplexer. + * \param mtu The maximum transmission unit size on each source CID channel. + * \param mps The maximum payload size on each source CID channel. + * \param credits The initial number of credits for each CID channel. + * \param numChans The number of channels in pCidList - 5 channels max. + * \param pCidList Array of 16-bit channel endpoint IDs. + * + * \return None. + */ + /*************************************************************************************************/ +static void l2cSendEnConnectReq(uint16_t handle, uint16_t psm, uint16_t mtu, uint16_t mps, + uint16_t credits, uint8_t numChans, uint16_t *pCidList) +{ + l2cChanCb_t *pChanCb; + uint8_t *pPacket; + uint8_t *p; + uint8_t i; + uint8_t len; + + WSF_ASSERT(numChans <= L2C_MAX_EN_CHAN); + + len = L2C_SIG_EN_CONNECT_REQ_LEN + numChans * sizeof(uint16_t); + + /* allocate msg buffer */ + if ((pPacket = l2cMsgAlloc(L2C_SIG_PKT_BASE_LEN + len)) != NULL) + { + /* build message */ + p = pPacket + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, L2C_SIG_EN_CONNECT_REQ); /* command code */ + UINT8_TO_BSTREAM(p, l2cCb.identifier); /* identifier */ + + for (i = 0; i < numChans; i++) + { + if (pCidList[i]) + { + pChanCb = l2cChanCbByCid(pCidList[i]); + pChanCb->identifier = l2cCb.identifier; + } + } + + l2cCb.identifier = L2C_NEXT_ID(l2cCb.identifier); + UINT16_TO_BSTREAM(p, (uint16_t) len); /* parameter length */ + UINT16_TO_BSTREAM(p, psm); /* protocol slave multiplexer */ + UINT16_TO_BSTREAM(p, mtu); /* maximum transimission unit */ + UINT16_TO_BSTREAM(p, mps); /* maximum pdu size */ + UINT16_TO_BSTREAM(p, credits); /* initial credits */ + + for (i = 0; i < numChans; i++) + { + UINT16_TO_BSTREAM(p, pCidList[i]); /* channel endpoint id */ + } + + /* send packet */ + L2cDataReq(L2C_CID_LE_SIGNALING, handle, (L2C_SIG_HDR_LEN + len), pPacket); + + /* start timer */ + pChanCb = l2cChanCbByCid(pCidList[0]); + WsfTimerStartSec(&pChanCb->reqTimer, pL2cCfg->reqTimeout); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send an enhanced connection response. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param mtu The maximum transmission unit size on each source CID channel. + * \param mps The maximum payload size on each source CID channel. + * \param credits The initial number of credits for each CID channel. + * \param result The result of the enhanced connection request. + * \param numChans The number of channels in pCidList - 5 channels max. + * \param pCidList Array of 16-bit channel endpoint IDs. + * + * \return None. + */ + /*************************************************************************************************/ +static void l2cSendEnConnectRsp(uint16_t handle, uint8_t identifier, uint16_t mtu, uint16_t mps, + uint16_t credits, uint16_t result, uint8_t numChans, uint16_t *pCidList) +{ + uint8_t *pPacket; + uint8_t *p; + uint8_t i; + uint8_t len; + + WSF_ASSERT(numChans <= L2C_MAX_EN_CHAN); + + len = L2C_SIG_EN_CONNECT_RSP_LEN + numChans * sizeof(uint16_t); + + /* allocate msg buffer */ + if ((pPacket = l2cMsgAlloc(L2C_SIG_PKT_BASE_LEN + len)) != NULL) + { + /* build message */ + p = pPacket + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, L2C_SIG_EN_CONNECT_RSP); /* command code */ + UINT8_TO_BSTREAM(p, identifier); /* identifier */ + UINT16_TO_BSTREAM(p, (uint16_t) len); /* parameter length */ + UINT16_TO_BSTREAM(p, mtu); /* maximum transimission unit */ + UINT16_TO_BSTREAM(p, mps); /* maximum pdu size */ + UINT16_TO_BSTREAM(p, credits); /* initial credits */ + UINT16_TO_BSTREAM(p, result); /* req result */ + + for (i = 0; i < numChans; i++) + { + UINT16_TO_BSTREAM(p, pCidList[i]); /* channel endpoint id */ + } + + /* send packet */ + L2cDataReq(L2C_CID_LE_SIGNALING, handle, (L2C_SIG_HDR_LEN + len), pPacket); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send an enhanced reconfiguration request. + * + * \param handle The connection handle. + * \param mtu The maximum transmission unit size on each source CID channel. + * \param mps The maximum payload size on each source CID channel. + * \param numChans The number of channels in pCidList - 5 channels max. + * \param pCidList Array of 16-bit channel endpoint IDs. + * + * \return None. + */ + /*************************************************************************************************/ +static void l2cSendEnReconfigReq(uint16_t handle, uint16_t mtu, uint16_t mps, uint8_t numChans, + uint16_t *pCidList) +{ + l2cChanCb_t *pChanCb; + uint8_t *pPacket; + uint8_t *p; + uint8_t i; + uint8_t len; + + WSF_ASSERT(numChans <= L2C_MAX_EN_CHAN); + + len = L2C_SIG_EN_RECONFIG_REQ_LEN + numChans * sizeof(uint16_t); + + /* allocate msg buffer */ + if ((pPacket = l2cMsgAlloc(L2C_SIG_PKT_BASE_LEN + len)) != NULL) + { + /* build message */ + p = pPacket + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, L2C_SIG_EN_RECONFIG_REQ); /* command code */ + UINT8_TO_BSTREAM(p, l2cCb.identifier); /* identifier */ + + for (i = 0; i < numChans; i++) + { + if (pCidList[i]) + { + pChanCb = l2cChanCbByCid(pCidList[i]); + + if (pChanCb && pChanCb->state == L2C_CHAN_STATE_CONNECTED) + { + pChanCb->identifier = l2cCb.identifier; + pChanCb->pendingMps = mps; + pChanCb->pendingMtu = mtu; + } + else + { + /* Lost connection. Free packet and give up. Event to higher layer? */ + WsfMsgFree(pPacket); + return; + } + } + } + + l2cCb.identifier = L2C_NEXT_ID(l2cCb.identifier); + UINT16_TO_BSTREAM(p, (uint16_t) len); /* parameter length */ + UINT16_TO_BSTREAM(p, mtu); /* maximum transimission unit */ + UINT16_TO_BSTREAM(p, mps); /* maximum pdu size */ + + for (i = 0; i < numChans; i++) + { + UINT16_TO_BSTREAM(p, pCidList[i]); /* channel endpoint id */ + } + + /* send packet */ + L2cDataReq(L2C_CID_LE_SIGNALING, handle, (L2C_SIG_HDR_LEN + len), pPacket); + + /* start timer */ + pChanCb = l2cChanCbByCid(pCidList[0]); + WsfTimerStartSec(&pChanCb->reqTimer, pL2cCfg->reqTimeout); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send an enhanced reconfiguration response. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param result The result of the operation. + * + * \return None. + */ + /*************************************************************************************************/ +static void l2cSendEnReconfigRsp(uint16_t handle, uint8_t identifier, uint16_t result) +{ + uint8_t *pPacket; + uint8_t *p; + + /* allocate msg buffer */ + if ((pPacket = l2cMsgAlloc(L2C_SIG_PKT_BASE_LEN + L2C_SIG_EN_RECONFIG_RSP_LEN)) != NULL) + { + /* build message */ + p = pPacket + L2C_PAYLOAD_START; + UINT8_TO_BSTREAM(p, L2C_SIG_EN_RECONFIG_RSP); /* command code */ + UINT8_TO_BSTREAM(p, identifier); /* identifier */ + UINT16_TO_BSTREAM(p, L2C_SIG_EN_RECONFIG_RSP_LEN); /* parameter length */ + UINT16_TO_BSTREAM(p, result); /* result code */ + + /* send packet */ + L2cDataReq(L2C_CID_LE_SIGNALING, handle, (L2C_SIG_HDR_LEN + L2C_SIG_EN_RECONFIG_RSP_LEN), pPacket); + } +} + /*************************************************************************************************/ /*! * \brief Disconnect a channel. @@ -794,7 +1150,6 @@ static void l2cDisconnectChannel(l2cChanCb_t *pChanCb) l2cSendDisconnectReq(pChanCb->pConnCb->handle, pChanCb->peerCid, pChanCb->localCid, pChanCb); } - /*************************************************************************************************/ /*! * \brief L2CAP data reassembly function. @@ -825,6 +1180,8 @@ static void l2CocDataReassemble(l2cChanCb_t *pChanCb, uint16_t len, uint8_t *pPa { /* get sdu len */ BSTREAM_TO_UINT16(sduLen, pPacket); + + L2C_TRACE_INFO2("l2CocDataReassemble: sduLen:%d len:%d", sduLen, len); /* verify sdu len not greater than our mtu */ if (sduLen > pChanCb->pRegCb->reg.mtu) @@ -845,7 +1202,7 @@ static void l2CocDataReassemble(l2cChanCb_t *pChanCb, uint16_t len, uint8_t *pPa dataInd.dataLen = sduLen; (*pChanCb->pRegCb->cback)((l2cCocEvt_t *) &dataInd); } - else if ((sduLen + L2C_LE_SDU_HDR_LEN) > len) + else if ((len >= L2C_LE_SDU_HDR_LEN) && ((sduLen + L2C_LE_SDU_HDR_LEN) > len)) { /* reassembly required; allocate reassembly buffer */ if ((pChanCb->pRxPkt = WsfMsgDataAlloc(sduLen, 0)) != NULL) @@ -896,6 +1253,8 @@ static void l2CocDataReassemble(l2cChanCb_t *pChanCb, uint16_t len, uint8_t *pPa l2cDisconnectChannel(pChanCb); L2C_TRACE_WARN2("too much data currLen:%d payload len:%d", pChanCb->rxCurrLen, len); + WsfMsgFree(pChanCb->pRxPkt); + pChanCb->pRxPkt = NULL; } } } @@ -969,7 +1328,7 @@ static void l2cProcFlowControlCredit(uint16_t handle, uint8_t identifier, uint8_ BSTREAM_TO_UINT16(cid, pPacket); BSTREAM_TO_UINT16(credits, pPacket); - if ((pChanCb = l2cChanCbByCidState(cid, L2C_CHAN_STATE_CONNECTED)) != NULL) + if ((pChanCb = l2cChanCbByPeerCid(handle, cid)) != NULL) { if (credits != 0) { @@ -1045,7 +1404,7 @@ static void l2cProcLeConnectReq(uint16_t handle, uint8_t identifier, uint8_t *pP if ((result = l2cCheckSecurity(connId, pRegCb)) == L2C_CONN_SUCCESS) { /* allocate channel */ - if ((pChanCb = l2cChanCbAlloc(L2C_CHAN_STATE_CONNECTED)) != NULL) + if (pRegCb->acceptCback(connId, 1) && (pChanCb = l2cChanCbAlloc(L2C_CHAN_STATE_CONNECTED)) != NULL) { /* initialize control block */ pChanCb->pRegCb = pRegCb; @@ -1265,6 +1624,434 @@ static bool_t l2cProcCommandRej(uint16_t handle, uint8_t identifier, uint8_t *pP return FALSE; } +/*************************************************************************************************/ +/*! + * \brief Process an enhanced connection request message from peer. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param pPacket Packet data. + * \param len Length of pPacket in bytes. + * + * \return TRUE if command processed, FALSE otherwise. + */ + /*************************************************************************************************/ +static bool_t l2cProcEnConnectReq(uint16_t handle, uint8_t identifier, uint8_t *pPacket, uint16_t len) +{ + dmConnId_t connId; + uint8_t numChans = (len - L2C_SIG_EN_CONNECT_REQ_LEN) / sizeof(uint16_t); + + if (numChans <= 0 || numChans > L2C_MAX_EN_CHAN) + { + return FALSE; + } + + /* get conn ID for handle */ + if ((connId = DmConnIdByHandle(handle)) != DM_CONN_ID_NONE) + { + l2cCocEnConnectInd_t connInd; + uint16_t cidList[L2C_MAX_EN_CHAN]; + uint16_t psm, mps, mtu; + uint16_t localMps = 0, localMtu = 0, localCredits = 0; + uint16_t result = L2C_CONN_SUCCESS; + l2cChanCb_t *pChanCb = NULL; + uint8_t cidLen = 0; + l2cRegCb_t *pRegCb; + + memset(cidList, 0, sizeof(cidList)); + + /* parse psm */ + BSTREAM_TO_UINT16(psm, pPacket); + + if ((pRegCb = l2cRegCbAccept(connId, psm)) != NULL) + { + uint16_t credits; + uint8_t permittedNumChannels = pRegCb->acceptCback(connId, numChans); + + /* parse parameters */ + BSTREAM_TO_UINT16(mtu, pPacket); + BSTREAM_TO_UINT16(mps, pPacket); + BSTREAM_TO_UINT16(credits, pPacket); + + /* update local mps, mtu, and initial credits */ + localMps = pRegCb->reg.mps; + localMtu = pRegCb->reg.mtu; + localCredits = pRegCb->reg.credits; + + if (l2cCocCb.errTest != L2C_CONN_SUCCESS) + { + result = l2cCocCb.errTest; + } + + /* check security level */ + else if ((result = l2cCheckSecurity(connId, pRegCb)) == L2C_CONN_SUCCESS) + { + uint8_t i; + + for (i = 0; i < numChans; i++) + { + uint16_t peerCid; + + /* parse peer cid */ + BSTREAM_TO_UINT16(peerCid, pPacket); + + if (peerCid) + { + /* check if peer CID already allocated to this psm */ + if (!l2cCheckPeerCid(connId, peerCid, pRegCb)) + { + /* allocate channel */ + if ((permittedNumChannels > 0) && (pChanCb = l2cChanCbAlloc(L2C_CHAN_STATE_CONNECTED)) != NULL) + { + /* initialize control block */ + pChanCb->pRegCb = pRegCb; + pChanCb->pConnCb = l2cConnCbById(connId); + pChanCb->psm = psm; + pChanCb->peerMps = mps; + pChanCb->peerMtu = mtu; + pChanCb->peerCredits = credits; + pChanCb->peerCid = peerCid; + + pChanCb->localCredits = localCredits; + + pChanCb->role = L2C_COC_ROLE_ACCEPTOR; + + cidList[i] = pChanCb->localCid; + cidLen++; + permittedNumChannels--; + } + else + { + /* some refused - channel allocation failed */ + result = L2C_CONN_FAIL_RES; + } + } + else + { + /* some refused - peer CID already allocated to this psm */ + result = L2C_CONN_FAIL_ALLOCATED_SCID; + } + } + } + } + } + else + { + /* all refused - not registered on this psm */ + result = L2C_CONN_FAIL_PSM; + } + + if (pChanCb) + { + /* if a channel was created, send indication to higher level */ + connInd.hdr.event = L2C_COC_EN_CONNECT_IND; + connInd.hdr.param = connId; + connInd.hdr.status = (uint8_t) result; + connInd.mps = mps; + connInd.mtu = mtu; + connInd.cidLen = cidLen; + connInd.req = TRUE; + memcpy(connInd.cidList, cidList, sizeof(cidList)); + + (*pChanCb->pRegCb->cback)((l2cCocEvt_t *) &connInd); + } + + l2cSendEnConnectRsp(handle, identifier, localMtu, localMps, localCredits, result, numChans, cidList); + + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Process an enhanced connection response message from peer. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param pPacket Packet data. + * \param len Length of pPacket in bytes. + * + * \return TRUE if command processed, FALSE otherwise. + */ + /*************************************************************************************************/ +static bool_t l2cProcEnConnectRsp(uint16_t handle, uint8_t identifier, uint8_t* pPacket, uint16_t len) +{ + l2cCocEnConnectInd_t connInd; + uint8_t numChans = (len - L2C_SIG_EN_CONNECT_RSP_LEN) / sizeof(uint16_t); + uint16_t mps, mtu, credits, result; + dmConnId_t connId; + l2cChanCb_t *pChanCb; + l2cRegCb_t *pRegCb; + uint16_t cidList[L2C_MAX_EN_CHAN]; + uint8_t i; + + /* get conn ID for handle */ + if ((connId = DmConnIdByHandle(handle)) != DM_CONN_ID_NONE) + { + l2cChanCb_t **pChanList; + + /* clear CID list */ + memset(cidList, 0, sizeof(cidList)); + + /* get the list of channels for the identifier */ + pChanList = l2cGetChanCbListByIdentifier(connId, identifier, L2C_CHAN_STATE_CONNECTING); + + /* stop timer */ + pChanCb = pChanList[0]; + WsfTimerStop(&pChanCb->reqTimer); + + /* store a registration control block for sending an indication */ + pRegCb = pChanCb->pRegCb; + + /* parse parameters */ + BSTREAM_TO_UINT16(mtu, pPacket); + BSTREAM_TO_UINT16(mps, pPacket); + BSTREAM_TO_UINT16(credits, pPacket); + BSTREAM_TO_UINT16(result, pPacket); + + if ((result == L2C_CONN_SUCCESS) || (result == L2C_CONN_FAIL_RES) || + (result == L2C_CONN_FAIL_INVALID_SCID) || (result == L2C_CONN_FAIL_ALLOCATED_SCID)) + { + for (i = 0; i < L2C_MAX_EN_CHAN; i++) + { + uint16_t peerCid; + + if (pChanList[i] == NULL) + { + break; + } + + BSTREAM_TO_UINT16(peerCid, pPacket); + + if ((peerCid == 0) || (i >= numChans)) + { + /* Peer rejected this channel. Free channel. */ + l2cChanCbDealloc(pChanList[i]); + } + else + { + /* Complete channel */ + pChanCb = pChanList[i]; + + /* store parameters */ + pChanCb->state = L2C_CHAN_STATE_CONNECTED; + + pChanCb->peerMps = (mps < pChanCb->pRegCb->reg.mps) ? mps : pChanCb->pRegCb->reg.mps; + pChanCb->peerMtu = mtu; + pChanCb->peerCredits = credits; + pChanCb->localCredits = pChanCb->pRegCb->reg.credits; + pChanCb->peerCid = peerCid; + + /* maintain channel list for indication to higher level */ + cidList[i] = pChanCb->localCid; + } + } + } + else + { + /* All connections refused */ + for (i = 0; i < L2C_MAX_EN_CHAN; i++) + { + if (pChanList[i]) + { + l2cChanCbDealloc(pChanList[i]); + } + } + } + + /* send indication to higher level */ + connInd.hdr.event = L2C_COC_EN_CONNECT_IND; + connInd.hdr.param = pChanCb->pConnCb->connId; + connInd.hdr.status = (uint8_t) result; + connInd.mps = mps; + connInd.mtu = mtu; + connInd.cidLen = numChans; + connInd.req = FALSE; + memcpy(connInd.cidList, cidList, sizeof(cidList)); + + (*pRegCb->cback)((l2cCocEvt_t *) &connInd); + + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Process an enhanced reconfigure request message from peer. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param pPacket Packet data. + * \param len Length of pPacket in bytes. + * + * \return TRUE if command processed, FALSE otherwise. + */ + /*************************************************************************************************/ +static bool_t l2cProcEnReconfigReq(uint16_t handle, uint8_t identifier, uint8_t* pPacket, uint16_t len) +{ + l2cCocEnReconfigInd_t reconInd; + uint8_t numChans = (len - L2C_SIG_EN_RECONFIG_REQ_LEN) / sizeof(uint16_t); + uint16_t mps, mtu; + dmConnId_t connId; + l2cChanCb_t *pChanCb = NULL; + l2cRegCb_t *pRegCb = NULL; + uint8_t i, cidPos = 0; + uint16_t result = HCI_SUCCESS; + + memset(&reconInd, 0, sizeof(reconInd)); + + /* get conn ID for handle */ + if ((connId = DmConnIdByHandle(handle)) != DM_CONN_ID_NONE) + { + if (l2cCocCb.errTest != L2C_CONN_SUCCESS) + { + result = l2cCocCb.errTest; + } + else + { + BSTREAM_TO_UINT16(mtu, pPacket); + BSTREAM_TO_UINT16(mps, pPacket); + + for (i = 0; i < numChans; i++) + { + uint16_t peerCid; + + BSTREAM_TO_UINT16(peerCid, pPacket); + + if (peerCid != 0) + { + if ((pChanCb = l2cChanCbByPeerCid(handle, peerCid)) != NULL) + { + if (mtu < pChanCb->peerMtu) + { + result = L2C_RECONFIG_FAIL_MTU; + break; + } + + if ((mps < pChanCb->peerMps) && (numChans != 1)) + { + result = L2C_RECONFIG_FAIL_MPS; + break; + } + + /* maintain channel list for indication to higher level */ + reconInd.cidList[cidPos++] = pChanCb->localCid; + pRegCb = pChanCb->pRegCb; + } + else + { + result = L2C_RECONFIG_FAIL_CID; + pRegCb = NULL; + break; + } + } + } + + /* Only modify MTU and MPS if value check above passes */ + if (result == HCI_SUCCESS) + { + for (i = 0; i < numChans; i++) + { + if ((reconInd.cidList[i] != 0) && ((pChanCb = l2cChanCbByCid(reconInd.cidList[i])) != NULL)) + { + /* modify the configuration for the channel */ + pChanCb->peerMtu = mtu; + pChanCb->peerMps = mps; + } + } + } + + if (pChanCb && pRegCb) + { + /* send indication to higher level */ + reconInd.hdr.event = L2C_COC_EN_RECONFIG_IND; + reconInd.hdr.param = pChanCb->pConnCb->connId; + reconInd.hdr.status = HCI_SUCCESS; + reconInd.mps = mps; + reconInd.mtu = mtu; + reconInd.cidLen = cidPos; + reconInd.req = TRUE; + + (*pRegCb->cback)((l2cCocEvt_t *) &reconInd); + } + } + + l2cSendEnReconfigRsp(handle, identifier, result); + + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Process an enhanced reconfigure response message from peer. + * + * \param handle The connection handle. + * \param identifier Identifier value in received request. + * \param pPacket Packet data. + * \param len Length of pPacket in bytes. + * + * \return TRUE if command processed, FALSE otherwise. + */ + /*************************************************************************************************/ +static bool_t l2cProcEnReconfigRsp(uint16_t handle, uint8_t identifier, uint8_t* pPacket) +{ + l2cCocEnReconfigInd_t reconInd; + l2cChanCb_t *pChanCb; + l2cChanCb_t **pChanList; + l2cRegCb_t *pRegCb; + uint8_t i, cidPos = 0; + uint16_t result; + + /* get the list of channels for the identifier */ + pChanList = l2cGetChanCbListByIdentifier(DmConnIdByHandle(handle), identifier, L2C_CHAN_STATE_CONNECTED); + + /* stop timer */ + pChanCb = pChanList[0]; + WsfTimerStop(&pChanCb->reqTimer); + + /* store a registration control block for sending an indication */ + pRegCb = pChanCb->pRegCb; + + BSTREAM_TO_UINT16(result, pPacket); + + if (result == HCI_SUCCESS) + { + for (i = 0; i < L2C_MAX_EN_CHAN; i++) + { + if (pChanList[i]) + { + reconInd.cidList[cidPos++] = pChanList[i]->localCid; + + pChanList[i]->peerMtu = pChanList[i]->pendingMtu; + pChanList[i]->pRegCb->reg.mtu = pChanList[i]->pendingMtu; + + pChanList[i]->peerMps = pChanList[i]->pendingMps; + pChanList[i]->pRegCb->reg.mps = pChanList[i]->pendingMps; + } + } + } + + /* send indication to higher level */ + reconInd.hdr.event = L2C_COC_EN_RECONFIG_IND; + reconInd.hdr.param = pChanCb->pConnCb->connId; + reconInd.hdr.status = (uint8_t) result; + reconInd.mps = pChanCb->peerMps; + reconInd.mtu = pChanCb->peerMtu; + reconInd.cidLen = cidPos; + reconInd.req = FALSE; + + (*pRegCb->cback)((l2cCocEvt_t *) &reconInd); + + return TRUE; +} + /*************************************************************************************************/ /*! * \brief Manage local credits. @@ -1396,6 +2183,26 @@ void l2cCocSignalingCback(uint16_t handle, uint16_t l2cLen, uint8_t *pPacket) l2cRxSignalingPkt(handle, l2cLen, pPacket); } } + /* if enhanced connection request */ + else if ((code == L2C_SIG_EN_CONNECT_REQ) && (len >= L2C_SIG_EN_CONNECT_REQ_LEN)) + { + l2cProcEnConnectReq(handle, id, p, len); + } + /* if enhanced connection response */ + else if ((code == L2C_SIG_EN_CONNECT_RSP) && (len >= L2C_SIG_EN_CONNECT_RSP_LEN)) + { + l2cProcEnConnectRsp(handle, id, p, len); + } + /* if enhanced reconfiguration request */ + else if ((code == L2C_SIG_EN_RECONFIG_REQ) && (len >= L2C_SIG_EN_RECONFIG_REQ_LEN)) + { + l2cProcEnReconfigReq(handle, id, p, len); + } + /* if enhanced reconfiguration response */ + else if ((code == L2C_SIG_EN_RECONFIG_RSP) && (len >= L2C_SIG_EN_RECONFIG_RSP_LEN)) + { + l2cProcEnReconfigRsp(handle, id, p); + } /* else pass to main signaling packet processing function */ else { @@ -1567,6 +2374,51 @@ static void l2cCocApiDisconnectReq(l2cCocMsg_t *pMsg) } } +/*************************************************************************************************/ +/*! + * \brief Process ae enhanced connection request from API. + * + * \param pMsg Message buffer. + * + * \return None. + */ + /*************************************************************************************************/ +void l2cCocApiEnConnectReq(l2cCocMsg_t *pMsg) +{ + l2cApiEnConnectReq_t *pReq = &pMsg->enConnectReq; + l2cChanCb_t *pChanCb = l2cChanCbByCid(pReq->chanList[0]); + + /* verify still in connecting state (link could have been disconnected) */ + if (pChanCb->state == L2C_CHAN_STATE_CONNECTING) + { + l2cCocReg_t *pRegCb = &pChanCb->pRegCb->reg; + + l2cSendEnConnectReq(pReq->handle, pReq->psm, pRegCb->mtu, pRegCb->mps, pReq->credits, + pReq->numChan, pReq->chanList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Process ae enhanced reconfigure request from API. + * + * \param pMsg Message buffer. + * + * \return None. + */ + /*************************************************************************************************/ +void l2cCocApiEnReconfigReq(l2cCocMsg_t *pMsg) +{ + l2cApiEnReconfigReq_t *pReq = &pMsg->enReconfigReq; + l2cChanCb_t *pChanCb = l2cChanCbByCid(pReq->chanList[0]); + + /* verify still in connecting state (link could have been disconnected) */ + if (pChanCb->state == L2C_CHAN_STATE_CONNECTED) + { + l2cSendEnReconfigReq(pReq->handle, pReq->mtu, pReq->mps, pReq->numChan, pReq->chanList); + } +} + /*************************************************************************************************/ /*! * \brief Process a request timeout. @@ -1653,6 +2505,14 @@ void L2cCocHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) l2cCocReqTimeout(pMsg); break; + case L2C_MSG_API_EN_CONNECT_REQ: + l2cCocApiEnConnectReq((l2cCocMsg_t*)pMsg); + break; + + case L2C_MSG_API_EN_RECONFIG_REQ: + l2cCocApiEnReconfigReq((l2cCocMsg_t*)pMsg); + break; + default: break; } @@ -1695,6 +2555,28 @@ l2cCocRegId_t L2cCocRegister(l2cCocCback_t cback, l2cCocReg_t *pReg) return L2C_COC_REG_ID_NONE; } +/*************************************************************************************************/ +/*! + * \brief Set the channel accept callback. + * + * \param regId Registration instance ID. + * \param cback Client callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void L2cCocSetAcceptCback(l2cCocRegId_t regId, l2cCocAcceptCb_t cback) +{ + l2cRegCb_t *pRegCb = l2cRegCbById(regId); + + WSF_ASSERT(cback != NULL); + WSF_ASSERT(pRegCb); + + WsfTaskLock(); + pRegCb->acceptCback = cback; + WsfTaskUnlock(); +} + /*************************************************************************************************/ /*! * \brief Deregister and deallocate a connection oriented channel registration instance. @@ -1792,7 +2674,6 @@ void L2cCocDisconnectReq(uint16_t cid) } } - /*************************************************************************************************/ /*! * \brief Send an L2CAP data packet on the given connection oriented CID. @@ -1838,6 +2719,148 @@ void L2cCocDataReq(uint16_t cid, uint16_t len, uint8_t *pPayload) } } +/*************************************************************************************************/ +/*! + * \brief Send a request to open enhanced credit based channels. + * + * \param connId DM connection ID. + * \param regId The associated registration instance. + * \param psm The protocol slave multiplexer. + * \param credits The initial number of credits for each CID channel. + * \param numChan The number of channels to create - L2C_MAX_EN_CHAN max. + * + * \return FALSE if unable make request, else TRUE. + */ +/*************************************************************************************************/ +bool_t L2cCocEnhancedConnectReq(dmConnId_t connId, l2cCocRegId_t regId, uint16_t psm, + uint16_t credits, uint8_t numChan) +{ + l2cApiEnConnectReq_t *pMsg; + l2cChanCb_t *pChanCb; + l2cConnCb_t *pConnCb = l2cConnCbById(connId);; + l2cRegCb_t *pRegCb = l2cRegCbById(regId); + bool_t success = FALSE; + uint8_t i; + + WSF_ASSERT(pRegCb); + + WsfTaskLock(); + + /* verify connected and resources available */ + if (numChan <= L2C_MAX_EN_CHAN && pConnCb && (l2cVerifyFreeChannels(numChan))) + { + if (pRegCb->inUse && connId != DM_CONN_ID_NONE) + { + /* alocate message buffer */ + if ((pMsg = WsfMsgAlloc(sizeof(l2cApiEnConnectReq_t))) != NULL) + { + /* unused channels should be zero */ + memset(pMsg->chanList, 0, sizeof(pMsg->chanList)); + + /* allocate channels */ + for (i = 0; i < numChan; i++) + { + pChanCb = l2cChanCbAlloc(L2C_CHAN_STATE_CONNECTING); + + WSF_ASSERT(pChanCb); + pChanCb->pRegCb = pRegCb; + pChanCb->pConnCb = pConnCb; + pChanCb->localCredits = credits; + + pMsg->chanList[i] = pChanCb->localCid; + } + + /* copy message parameters */ + pMsg->psm = psm; + pMsg->credits = credits; + pMsg->handle = pConnCb->handle; + pMsg->numChan = numChan; + + /* send message */ + pMsg->hdr.event = L2C_MSG_API_EN_CONNECT_REQ; + WsfMsgSend(l2cCocCb.handlerId, pMsg); + success = TRUE; + } + } + } + + WsfTaskUnlock(); + return success; +} + +/*************************************************************************************************/ +/*! + * \brief Send a request to reconfigure enhanced credit based channels. + * + * \param connId DM connection ID. + * \param mtu The maximum transmission unit of each source CID channel. + * \param mps The maximum payload size on each source CID channel. + * \param numChan The number of channels to create (1 to L2C_MAX_EN_CHAN). + * \param pChanList A list of local CID to Reconfig (L2C_MAX_EN_CHAN channels, set unused to 0). + * + * \return FALSE if unable make request, else TRUE. + */ + /*************************************************************************************************/ +bool_t L2cCocEnhancedReconfigReq(dmConnId_t connId, uint16_t mtu, uint16_t mps, + uint8_t numChan, uint16_t *pChanList) +{ + l2cApiEnReconfigReq_t* pMsg; + l2cConnCb_t* pConnCb = l2cConnCbById(connId); + l2cChanCb_t *pChanCb; + bool_t success = FALSE; + uint16_t maxMtu = 0, maxMps = 0; + uint8_t i; + + WsfTaskLock(); + + /* alocate message buffer */ + if ((numChan <= L2C_MAX_EN_CHAN) && pConnCb) + { + for (i = 0; i < numChan; i++) + { + pChanCb = l2cChanCbByCid(pChanList[i]); + + if (!pChanCb || (pChanCb->state != L2C_CHAN_STATE_CONNECTED)) + { + WsfTaskUnlock(); + return FALSE; + } + + /* Record the maxMtu and maxMps from all channels for mtu and mps validation. */ + if (pChanCb->peerMtu > maxMtu) + { + maxMtu = pChanCb->peerMtu; + } + + if (pChanCb->peerMps > maxMps) + { + maxMps = pChanCb->peerMps; + } + } + + /* Check that MTU is greater or equal to greatest of all mtu and do the same for MPS unless only 1 channel. */ + if ((mtu >= maxMtu) && ((numChan == 1) || (mps >= maxMps))) + { + if ((pMsg = WsfMsgAlloc(sizeof(l2cApiEnConnectReq_t))) != NULL) + { + pMsg->mtu = mtu; + pMsg->mps = mps; + pMsg->handle = pConnCb->handle; + pMsg->numChan = numChan; + memcpy(pMsg->chanList, pChanList, numChan * sizeof(uint16_t)); + + /* send message */ + pMsg->hdr.event = L2C_MSG_API_EN_RECONFIG_REQ; + WsfMsgSend(l2cCocCb.handlerId, pMsg); + success = TRUE; + } + } + } + + WsfTaskUnlock(); + return success; +} + /*************************************************************************************************/ /*! * \brief For testing purposes only. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.c index ccc00083fc9..988b73a6357 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP main module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.h index b36baf00aeb..c98dbc0155d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP main module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef L2C_MAIN_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_master.c index 8b8a9fb707c..0f6c8c0594c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_master.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP module for master operations. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP module for master operations. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_slave.c index 3fd1df2d2cd..e9a1ff23544 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/l2c/l2c_slave.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief L2CAP module for slave operations. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief L2CAP module for slave operations. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -88,10 +90,16 @@ static void l2cSlaveReqTimeout(wsfMsgHdr_t *pMsg) /*************************************************************************************************/ static void l2cSlaveRxSignalingPkt(uint16_t handle, uint16_t l2cLen, uint8_t *pPacket) { - uint8_t code; - uint8_t id; - uint16_t len; - uint16_t result; + uint8_t code; + uint8_t id; + uint16_t len; + uint16_t result; + dmConnId_t connId; + + if ((connId = DmConnIdByHandle(handle)) == DM_CONN_ID_NONE) + { + return; + } /* parse code, len, and identifier */ pPacket += L2C_PAYLOAD_START; @@ -111,16 +119,16 @@ static void l2cSlaveRxSignalingPkt(uint16_t handle, uint16_t l2cLen, uint8_t *pP * verify this is a conn param update rsp or command reject * verify parameter length */ - if ((id == l2cSlaveCb.signId[handle]) && + if ((id == l2cSlaveCb.signId[connId-1]) && (l2cLen == (len + L2C_SIG_HDR_LEN)) && (((code == L2C_SIG_CONN_UPDATE_RSP) && (len == L2C_SIG_CONN_UPDATE_RSP_LEN)) || (code == L2C_SIG_CMD_REJ))) { /* get last sent code */ - uint8_t lastCode = l2cSlaveCb.lastCode[handle]; + uint8_t lastCode = l2cSlaveCb.lastCode[connId-1]; /* clear pending signal id */ - l2cSlaveCb.signId[handle] = L2C_SIGNAL_ID_INVALID; + l2cSlaveCb.signId[connId-1] = L2C_SIGNAL_ID_INVALID; /* parse result parameter */ BSTREAM_TO_UINT16(result, pPacket); @@ -190,13 +198,17 @@ void L2cSlaveInit(void) /*************************************************************************************************/ void L2cDmSigReq(uint16_t handle, uint8_t code, uint16_t len, uint8_t *pParam) { - uint8_t *pPacket; - uint8_t *p; + uint8_t *pPacket; + uint8_t *p; + dmConnId_t connId; - WSF_ASSERT(handle < DM_CONN_MAX); + if ((connId = DmConnIdByHandle(handle)) == DM_CONN_ID_NONE) + { + return; + } /* record code */ - l2cSlaveCb.lastCode[handle] = code; + l2cSlaveCb.lastCode[connId-1] = code; /* Start signaling request timer and store handle */ WsfTimerStartSec(&l2cSlaveCb.reqTimer, L2C_SIG_REQ_TIMEOUT); @@ -208,7 +220,7 @@ void L2cDmSigReq(uint16_t handle, uint8_t code, uint16_t len, uint8_t *pParam) /* build message */ p = pPacket + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, code); /* command code */ - l2cSlaveCb.signId[handle] = l2cCb.identifier; + l2cSlaveCb.signId[connId-1] = l2cCb.identifier; UINT8_TO_BSTREAM(p, l2cCb.identifier); /* identifier */ l2cCb.identifier = L2C_NEXT_ID(l2cCb.identifier); UINT16_TO_BSTREAM(p, len); /* parameter length */ @@ -231,11 +243,17 @@ void L2cDmSigReq(uint16_t handle, uint8_t code, uint16_t len, uint8_t *pParam) /*************************************************************************************************/ void L2cDmConnUpdateReq(uint16_t handle, hciConnSpec_t *pConnSpec) { - uint8_t *pPacket; - uint8_t *p; + uint8_t *pPacket; + uint8_t *p; + dmConnId_t connId; + + if ((connId = DmConnIdByHandle(handle)) == DM_CONN_ID_NONE) + { + return; + } /* record code */ - l2cSlaveCb.lastCode[handle] = L2C_SIG_CONN_UPDATE_REQ; + l2cSlaveCb.lastCode[connId-1] = L2C_SIG_CONN_UPDATE_REQ; /* Start signaling request timer and store handle */ WsfTimerStartSec(&l2cSlaveCb.reqTimer, L2C_SIG_REQ_TIMEOUT); @@ -248,7 +266,7 @@ void L2cDmConnUpdateReq(uint16_t handle, hciConnSpec_t *pConnSpec) p = pPacket + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, L2C_SIG_CONN_UPDATE_REQ); /* command code */ UINT8_TO_BSTREAM(p, l2cCb.identifier); /* identifier */ - l2cSlaveCb.signId[handle] = l2cCb.identifier; + l2cSlaveCb.signId[connId-1] = l2cCb.identifier; l2cCb.identifier = L2C_NEXT_ID(l2cCb.identifier); UINT16_TO_BSTREAM(p, L2C_SIG_CONN_UPDATE_REQ_LEN); /* parameter length */ UINT16_TO_BSTREAM(p, pConnSpec->connIntervalMin); /* interval min */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_act.c index 9fe67eb1b6a..3c1ac366522 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_act.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP common utility functions and action functions. + * \file + * + * \brief SMP common utility functions and action functions. + * + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -159,6 +161,32 @@ void smpActPairingFailed(smpCcb_t *pCcb, smpMsg_t *pMsg) DmSmpCbackExec((dmEvt_t *) pMsg); } +/*************************************************************************************************/ +/*! + * \brief Response timeout on security request. + * + * \param pCcb Connection control block. + * \param pMsg State machine message. + * + * \return None. + */ +/*************************************************************************************************/ +void smpActSecReqTimeout(smpCcb_t *pCcb, smpMsg_t *pMsg) +{ + /* The initiator can ignore security request. Cancel pairing if paring/encryption was not + * completed, else assume the initiator ignored a request to change keys. */ + if (DmConnSecLevel(pCcb->connId) == DM_SEC_LEVEL_NONE) + { + smpActPairingFailed(pCcb, pMsg); + } + else + { + /* Cleanup and return to IDLE without failure */ + pMsg->hdr.event = SMP_MSG_INT_CLEANUP; + smpSmExecute(pCcb, pMsg); + } +} + /*************************************************************************************************/ /*! * \brief Pairing cancelled by user. @@ -820,7 +848,7 @@ void smpSmExecute(smpCcb_t *pCcb, smpMsg_t *pMsg) smpSmIf_t const *pSmIf; #if SMP_EXTRA_TRACE == TRUE - if (smpCb.lescSupported) + if (smpCb.lescSupported && pCcb->pScCcb && pCcb->pScCcb->lescEnabled) SMP_TRACE_INFO2("SMP Exe: evt=%s st=%s", smpEventStr(pMsg->hdr.event), smpStateStr(pCcb->state)); else #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_db.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_db.c index 3799c327648..cbd056aaab3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_db.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_db.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP device database. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP device database. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.c index a679512dcbf..ba4889305cc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP main module. + * \file + * + * \brief SMP main module. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.h index 3100bf3585b..45a07377508 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_main.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP main module. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMP_MAIN_H @@ -381,6 +382,7 @@ void smpCleanup(smpCcb_t *pCcb); void smpActCleanup(smpCcb_t *pCcb, smpMsg_t *pMsg); void smpSendPairingFailed(smpCcb_t *pCcb, uint8_t reason); void smpActPairingFailed(smpCcb_t *pCcb, smpMsg_t *pMsg); +void smpActSecReqTimeout(smpCcb_t *pCcb, smpMsg_t *pMsg); void smpActPairingCancel(smpCcb_t *pCcb, smpMsg_t *pMsg); void smpActStorePin(smpCcb_t *pCcb, smpMsg_t *pMsg); bool_t smpProcPairing(smpCcb_t *pCcb, uint8_t *pOob, uint8_t *pDisplay); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_non.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_non.c index fc73ede6be0..b024dc746c7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_non.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_non.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Simple implementation of SMP when not supported. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Simple implementation of SMP when not supported. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_act.c index 63131c195b6..f722964bb6b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_act.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP Secure Connections common action functions. + * \file + * + * \brief SMP Secure Connections common action functions. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.c index e5b89d351c2..00515542371 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP Secure Connections main module and utility functions. + * \file + * + * \brief SMP Secure Connections main module and utility functions. + * + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -661,6 +663,7 @@ uint8_t *smpEventStr(uint8_t eventId) case SMP_MSG_INT_PK_CMPL: return (uint8_t*) "INT_PK_CMPL"; case SMP_MSG_WSF_CMAC_CMPL: return (uint8_t*) "WSF_CMAC_CMPL"; case SMP_MSG_DH_CHECK_FAILURE: return (uint8_t*) "DH_CHECK_FAILURE"; + case SMP_MSG_INT_CLEANUP: return (uint8_t*) "INT_CLEANUP"; default: return (uint8_t*) "Unknown"; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.h index a63197e3ec6..e54242a9086 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smp_sc_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP main module header file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP main module header file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMP_SC_MAIN_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_act.c index 0e32fba540f..404a9e20dac 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_act.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP initiator state machine action functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP initiator state machine action functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_main.h index 46c51d47363..9fde4bac0c5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP initiator main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP initiator main module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMPI_MAIN_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_act.c index 8ef115bdc10..38ed4197099 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_act.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP Secure Connections initiator state machine action functions. + * \file + * + * \brief SMP Secure Connections initiator state machine action functions. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_sm.c index 2f991b22e12..68d20bee606 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_sm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sc_sm.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP Secure Connections initiator state machine. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP Secure Connections initiator state machine. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sm.c index 850f2f65661..b5bc5ba1a6a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpi_sm.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP initiator state machine. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP initiator state machine. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_act.c index 8917dae2865..086a013a445 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_act.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP responder state machine action functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP responder state machine action functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_main.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_main.h index e4ce0165177..69001fba74d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_main.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_main.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP responder main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP responder main module. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef SMPR_MAIN_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_act.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_act.c index 0ad796a0378..062799ba7c5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_act.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_act.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * Copyright (c) 2019-2020 Packetcraft, Inc. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief SMP Secure Connections responder state machine action functions. + * \file + * + * \brief SMP Secure Connections responder state machine action functions. + * + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_sm.c index cae5206c342..09a208b4735 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_sm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sc_sm.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP Secure Connections initiator state machine. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP Secure Connections initiator state machine. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,6 +38,7 @@ enum SMPR_SC_ACT_NONE, /*!< No Action */ SMPR_SC_ACT_CLEANUP, /*!< Process Pairing Cleanup */ SMPR_SC_ACT_PAIRING_FAILED, /*!< Process Pairing Failed */ + SMPR_SC_ACT_SEC_REQ_TO, /*!< Process Response timeout on security request */ SMPR_SC_ACT_PAIRING_CANCEL, /*!< Process Pairing Canceled */ SMPR_SC_ACT_SEND_PUB_KEY, /*!< Process Send Public Key */ SMPR_SC_ACT_STORE_LEGACY_PIN, /*!< Process Store Legacy Pin */ @@ -106,6 +109,7 @@ static const smpAct_t smprScActionTbl[] = smpActNone, smpScActCleanup, smpScActPairingFailed, + smpActSecReqTimeout, smpScActPairingCancel, smprScActSendPubKey, smpActStorePin, @@ -200,6 +204,8 @@ static const smpTblEntry_t smprScStateTblApiPairReq[] = {SMP_MSG_API_CANCEL_REQ, SMPR_SC_SM_ST_IDLE, SMPR_SC_ACT_CLEANUP}, {SMP_MSG_DM_ENCRYPT_CMPL, SMPR_SC_SM_ST_IDLE, SMPR_SC_ACT_CLEANUP}, {SMP_MSG_DM_ENCRYPT_FAILED, SMPR_SC_SM_ST_IDLE, SMPR_SC_ACT_CLEANUP}, + {SMP_MSG_INT_RSP_TIMEOUT, SMPR_SC_SM_ST_API_PAIR_REQ, SMPR_SC_ACT_SEC_REQ_TO}, + {SMP_MSG_INT_CLEANUP, SMPR_SC_SM_ST_IDLE, SMPR_SC_ACT_CLEANUP}, {0, 0, 0} }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sm.c index cd38e233195..a922f753e64 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/smp/smpr_sm.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief SMP responder state machine. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief SMP responder state machine. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,6 +37,7 @@ enum SMPR_ACT_NONE, /*!< No Action */ SMPR_ACT_CLEANUP, /*!< Process Pairing Cleanup */ SMPR_ACT_PAIRING_FAILED, /*!< Process Pairing Failed */ + SMPR_ACT_SEC_REQ_TO, /*!< Process Response timeout on security request */ SMPR_ACT_PAIRING_CANCEL, /*!< Process Pairing Canceled */ SMPR_ACT_STORE_PIN, /*!< Process Store Pin */ SMPR_ACT_PAIR_CNF_CALC_1, /*!< Process Confirm Value Calculation 1 */ @@ -75,6 +78,7 @@ static const smpAct_t smprActionTbl[] = smpActNone, smpActCleanup, smpActPairingFailed, + smpActSecReqTimeout, smpActPairingCancel, smpActStorePin, smpActPairCnfCalc1, @@ -134,6 +138,8 @@ static const smpTblEntry_t smprStateTblApiPairReq[] = {SMP_MSG_API_CANCEL_REQ, SMPR_SM_ST_IDLE, SMPR_ACT_CLEANUP}, {SMP_MSG_DM_ENCRYPT_CMPL, SMPR_SM_ST_IDLE, SMPR_ACT_CLEANUP}, {SMP_MSG_DM_ENCRYPT_FAILED, SMPR_SM_ST_IDLE, SMPR_ACT_CLEANUP}, + {SMP_MSG_INT_RSP_TIMEOUT, SMPR_SM_ST_API_PAIR_REQ, SMPR_ACT_SEC_REQ_TO}, + {SMP_MSG_INT_CLEANUP, SMPR_SM_ST_IDLE, SMPR_ACT_CLEANUP}, {0, 0, 0} }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_audio_amp.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_audio_amp.h deleted file mode 100644 index 2d809aaa43f..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_audio_amp.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Audio amplifier driver definition. - */ -/*************************************************************************************************/ - -#ifndef PAL_AUDIO_AMP_H -#define PAL_AUDIO_AMP_H - -#include "stack/platform/include/pal_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************************************** - Data Types -**************************************************************************************************/ - -/*! \brief Operational states. */ -typedef enum -{ - PAL_AUDIO_AMP_STATE_UNINIT = 0, /*!< Uninitialized state. */ - PAL_AUDIO_AMP_STATE_ERROR = 0, /*!< Error state. */ - PAL_AUDIO_AMP_STATE_READY, /*!< Ready state. */ - PAL_AUDIO_AMP_STATE_BUSY /*!< BUSY state. */ -} PalAudioAmpState_t; - -/************************************************************************************************** - Function Declarations -**************************************************************************************************/ - -/* Initialization */ -void PalAudioAmpInit(void); -void PalAudioAmpDeInit(void); - -/* Control and Status */ -PalAudioAmpState_t PalAudioAmpGetState(void); -uint8_t PalAudioAmpGetVol(void); -void PalAudioAmpSetVolUp(void); -void PalAudioAmpSetVolDown(void); -void PalAudioAmpMute(void); -void PalAudioAmpUnmute(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* PAL_AUDIO_AMP_H */ - diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb.h index c10b659a621..17d341712ba 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Baseband interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Baseband interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_BB_H #define PAL_BB_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -34,7 +36,7 @@ extern "C" { **************************************************************************************************/ /*! \brief Protocol types */ -enum +typedef enum { BB_PROT_NONE, /*!< Non-protocol specific operation. */ BB_PROT_BLE, /*!< Bluetooth Low Energy normal mode. */ @@ -42,7 +44,7 @@ enum BB_PROT_PRBS15, /*!< Enable the continuous PRBS15 transmit sequence. */ BB_PROT_15P4, /*!< 802.15.4. */ BB_PROT_NUM /*!< Number of protocols. */ -}; +} PalBbProt_t; /*! \brief Status codes */ enum @@ -60,13 +62,13 @@ enum }; /*! \brief PHY types. */ -enum +typedef enum { BB_PHY_BLE_1M = 1, /*!< Bluetooth Low Energy 1Mbps PHY. */ BB_PHY_BLE_2M = 2, /*!< Bluetooth Low Energy 2Mbps PHY. */ BB_PHY_BLE_CODED = 3, /*!< Bluetooth Low Energy Coded PHY (data coding unspecified). */ BB_PHY_15P4 = 4, /*!< 802.15.4 PHY. */ -}; +} PalBbPhy_t; /*! \brief PHY options. */ enum @@ -78,11 +80,11 @@ enum #ifndef BB_CLK_RATE_HZ /*! \brief BB clock rate in hertz. */ -#define BB_CLK_RATE_HZ 1000000 +#define BB_CLK_RATE_HZ 1000000 #endif /*! \brief Binary divide with 1,000,000 divisor (n[max]=0xFFFFFFFF). */ -#define BB_MATH_DIV_10E6(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(4295)) >> 32)) +#define BB_MATH_DIV_10E6(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(4295)) >> 32)) #if (BB_CLK_RATE_HZ == 1000000) /*! \brief Return microseconds (no conversion required). */ @@ -92,7 +94,7 @@ enum #define BB_US_TO_BB_TICKS(us) ((uint32_t)((us) << 3)) #elif (BB_CLK_RATE_HZ == 32768) /*! \brief Compute BB ticks from given time in microseconds (max time is interval=1,996s). */ -#define BB_US_TO_BB_TICKS(us) ((uint32_t)(((uint64_t)(us) * UINT64_C(549755)) >> 24)) /* calculated value may be one tick low */ +#define BB_US_TO_BB_TICKS(us) ((uint32_t)(((uint64_t)(us) * (uint64_t)(70368745)) >> 31)) /* calculated value may be one tick low */ #else /*! \brief Compute BB ticks from given time in microseconds (max time is interval=1,996s). */ #define BB_US_TO_BB_TICKS(us) BB_MATH_DIV_10E6((uint64_t)(us) * (uint64_t)(BB_CLK_RATE_HZ)) @@ -100,7 +102,6 @@ enum #define RTC_CLOCK_RATE 32768 #define USE_RTC_BB_CLK (BB_CLK_RATE_HZ == RTC_CLOCK_RATE) -#define HFCLK_OSC_SETTLE_TICKS (RTC_CLOCK_RATE / 1000) #if (BB_CLK_RATE_HZ == 1000000) /*! \brief BB ticks to microseconds (no conversion required). */ @@ -125,6 +126,15 @@ enum /*! \brief Typical operation setup delay in microseconds (BbRtCfg_t::schSetupDelayUs). */ #define BB_SCH_SETUP_DELAY_US 500 +/*! \brief Maximum time tick for 32 bit timer(1MHz) in microseconds (BbRtCfg_t::schSetupDelayUs). */ +#define BB_TIMER_1MHZ_MAX_VALUE_US 0xFFFFFFFF /* 2^32 - 1 = 0xFFFFFFFF. */ + +/*! \brief Maximum time tick for 32 bit timer(8MHz) in microseconds (BbRtCfg_t::schSetupDelayUs). */ +#define BB_TIMER_8MHZ_MAX_VALUE_US 0x1FFFFFFF /* 2^29 - 1 = 0x1FFFFFFF. */ + +/*! \brief Maximum time tick for 24 bit RTC counter(32768Hz) in microseconds. (BbRtCfg_t::BbTimerBoundaryUs) */ +#define BB_RTC_MAX_VALUE_US 511999999 /* 2^24 / 32768 * 10^6 - 1 = 512 * 10^6 - 1 = 511999999. */ + /************************************************************************************************** Type Definitions **************************************************************************************************/ @@ -139,6 +149,7 @@ typedef struct uint8_t rfSetupDelayUsec; /*!< RF setup delay in microseconds. */ uint16_t maxScanPeriodMsec; /*!< Maximum scan period in milliseconds. */ uint16_t schSetupDelayUsec; /*!< Schedule setup delay in microseconds. */ + uint32_t BbTimerBoundaryUsec; /*!< BB timer boundary translated in microseconds before wraparound. */ } PalBbCfg_t; /************************************************************************************************** @@ -155,8 +166,6 @@ typedef struct /*! * \brief Initialize the baseband driver. * - * \return None. - * * One-time initialization of baseband resources. This routine can be used to setup baseband * resources, load RF trim parameters and execute RF calibrations and seed the random number * generator. @@ -170,8 +179,6 @@ void PalBbInit(void); /*! * \brief Enable the BB hardware. * - * \return None. - * * This routine brings the BB hardware out of low power (enable power and clocks) just before a * first BB operation is executed. */ @@ -182,8 +189,6 @@ void PalBbEnable(void); /*! * \brief Disable the BB hardware. * - * \return None. - * * This routine signals the BB hardware to go into low power (disable power and clocks) after all * BB operations have been disabled. */ @@ -195,8 +200,6 @@ void PalBbDisable(void); * \brief Load BB timing configuration. * * \param pCfg Return configuration values. - * - * \return None. */ /*************************************************************************************************/ void PalBbLoadCfg(PalBbCfg_t *pCfg); @@ -210,17 +213,14 @@ void PalBbLoadCfg(PalBbCfg_t *pCfg); /*************************************************************************************************/ /*! - * \brief Get the current BB clock value. - * - * \param useRtcBBClk Use RTC BB clock. + * \brief Get the current BB clock value in microseconds. * * \return Current BB clock value, units are microseconds. * - * This routine reads the current value from the BB clock and returns its value. The clock should - * increment at the rate BB_CLK_RATE_HZ (wrapping as appropriate) whenever the BB is enabled. + * This routine reads the current value from the BB clock and returns its value. */ /*************************************************************************************************/ -uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk); +uint32_t PalBbGetCurrentTime(void); /*************************************************************************************************/ /*! @@ -245,8 +245,6 @@ bool_t PalBbGetTimestamp(uint32_t *pTime); * \param protId Protocol ID. * \param timerCback Timer IRQ callback. * \param radioCback Timer IRQ callback. - * - * \return None. */ /*************************************************************************************************/ void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCback_t radioCback); @@ -256,8 +254,6 @@ void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCb * \brief Set protocol ID. * * \param protId Protocol ID. - * - * \return None. */ /*************************************************************************************************/ void PalBbSetProtId(uint8_t protId); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_154.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_154.h new file mode 100644 index 00000000000..f0b46d61d92 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_154.h @@ -0,0 +1,661 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief IEEE 802.15.4 MAC Baseband driver interface file. + * + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_BB_154_H +#define PAL_BB_154_H + +#include "pal_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Minimum number of receive buffers. */ +#define PAL_BB_154_MIN_RX_BUF_CNT 2 /*!< PAL_BB_154_MIN_RX_BUF_CNT. */ +#define PAL_BB_154_RX_BUF_CNT 2 /*!< PAL_BB_154_RX_BUF_CNT. */ + +/*! \brief Driver status flags. */ +enum +{ + PAL_BB_154_FLAG_RX_ACK_CMPL = (1 << 0), /*!< Rx ack. completed. */ + PAL_BB_154_FLAG_TX_ACK_CMPL = (1 << 1), /*!< Tx ack. completed. */ + PAL_BB_154_FLAG_RX_ACK_START = (1 << 2), /*!< Rx ack. started. */ + PAL_BB_154_FLAG_TX_ACK_START = (1 << 3), /*!< Tx ack. started. */ +}; + +/*! \brief Operation flags. */ +enum +{ + PAL_BB_154_FLAG_TX_AUTO_RX_ACK = (1 << 0), /*!< Automatically wait for ACK after transmit completes. */ + PAL_BB_154_FLAG_RX_AUTO_TX_ACK = (1 << 1), /*!< Automatically send ACK after receive completes. */ + PAL_BB_154_FLAG_RX_WHILE_ED = (1 << 2), /*!< Receive any packet detected while performing ED. */ + PAL_BB_154_FLAG_DIS_CCA = (1 << 3), /*!< Disable CCA before transmit. */ + PAL_BB_154_FLAG_RAW = (1 << 4) /*!< Treat as raw frame */ +}; + +/*! \brief Receive flags. */ +enum +{ + PAL_BB_154_RX_FLAG_GO_IDLE = (1 << 0), /*!< Can go idle. */ + PAL_BB_154_RX_FLAG_SET_ACK_FP = (1 << 1) /*!< Set frame pending in ack. */ +}; + +/************************************************************************************************** + MAC addressing modes + 802.15.4-2006 Table 80 +**************************************************************************************************/ + +/*! \brief Addressing mode. */ +typedef enum +{ + PAL_BB_154_ADDR_MODE_NONE = 0, + PAL_BB_154_ADDR_MODE_SHORT = 2, + PAL_BB_154_ADDR_MODE_EXTENDED = 3 +} PalBb154AddrMode_t; + +/************************************************************************************************** + MAC frame types + 802.15.4-2006 Table 79 +**************************************************************************************************/ + +/*! \brief Values of frame type in FC. */ +typedef enum +{ + PAL_BB_154_FRAME_TYPE_BEACON = 0, + PAL_BB_154_FRAME_TYPE_DATA = 1, + PAL_BB_154_FRAME_TYPE_ACKNOWLEDGMENT = 2, + PAL_BB_154_FRAME_TYPE_MAC_COMMAND = 3, + PAL_BB_154_FRAME_TYPE_ILLEGAL4 = 4, + PAL_BB_154_FRAME_TYPE_ILLEGAL5 = 5, + PAL_BB_154_FRAME_TYPE_ILLEGAL6 = 6, + PAL_BB_154_FRAME_TYPE_ILLEGAL7 = 7 +} PalBb154FrameType_t; + +/************************************************************************************************** + MAC command types + 802.15.4-2006 Table 82 +**************************************************************************************************/ + +/*! \brief Values of MAC command type. */ +typedef enum +{ + PAL_BB_154_CMD_FRAME_TYPE_ASSOC_REQ = 1, + PAL_BB_154_CMD_FRAME_TYPE_ASSOC_RSP = 2, + PAL_BB_154_CMD_FRAME_TYPE_DISASSOC_NTF = 3, + PAL_BB_154_CMD_FRAME_TYPE_DATA_REQ = 4, + PAL_BB_154_CMD_FRAME_TYPE_PANID_CNFL_NTF = 5, + PAL_BB_154_CMD_FRAME_TYPE_ORPHAN_NTF = 6, + PAL_BB_154_CMD_FRAME_TYPE_BEACON_REQ = 7, + PAL_BB_154_CMD_FRAME_TYPE_COORD_REALIGN = 8, + PAL_BB_154_CMD_FRAME_TYPE_GTS_REQ = 9 +} PalBb154CmdType_t; + +/*! \brief MAC device type (vendor specific). */ +typedef enum +{ + PAL_BB_154_DEV_TYPE_DEVICE, /*!< Device is not a coordinator */ + PAL_BB_154_DEV_TYPE_COORD, /*!< Device is a coordinator but not a PAN coordinator */ + PAL_BB_154_DEV_TYPE_PAN_COORD, /*!< Device is a PAN coordinator */ +} PalBb154DevType_t; + +/* \brief Special addresses. */ +#define PAL_BB_154_BROADCAST_PANID 0xffff +#define PAL_BB_154_BROADCAST_ADDR 0xffff +#define PAL_BB_154_UNASSIGNED_ADDR 0xffff +#define PAL_BB_154_NO_SHT_ADDR 0xfffe +#define PAL_BB_154_UNASSIGNED_PAN_ID 0xffff + +/* \brief Address lengths. */ +#define PAL_BB_154_SHORT_ADDR_LEN 2 +#define PAL_BB_154_EXTENDED_ADDR_LEN 8 + +/*! \brief PAL_BB_154_FLAG_TX_RX_AUTO_ACK. */ +#define PAL_BB_154_FLAG_TX_RX_AUTO_ACK (PAL_BB_154_FLAG_TX_AUTO_RX_ACK | PAL_BB_154_FLAG_RX_AUTO_TX_ACK) + +/* \brief Symbols to microseconds for 802.15.4-2006 2.4GHz PHY */ +#define PAL_BB_154_SYMB_TO_US(x) ((x) * 16) /*!< PAL_BB_154_SYMB_TO_US. */ +#define PAL_BB_154_SYMB_TO_MS(x) (((x) * 16) / 1000) /*!< PAL_BB_154_SYMB_TO_MS. */ +#define PAL_BB_154_US_TO_SYMB(x) ((x) / 16) /*!< PAL_BB_154_US_TO_SYMB. */ + +/* \brief Transaction persistence time factor */ +#define PAL_BB_154_TPT_TO_MS(x) (((x) * 15723) >> 10) /*!< 15723/1024 approximates to 15.36 */ + +/*! \brief Energy detect threshold in dBm. */ +#define PAL_BB_154_ED_THRESHOLD -75 /*!< 10 dBm above 802.15.4 specified -85 dBm */ + +/************************************************************************************************** + MAC frame format + 802.15.4-2006 Section 7.2 +**************************************************************************************************/ + +/*! \brief Size of frame control in octets. */ +#define PAL_BB_154_FRAME_CONTROL_LEN 2 + +/*! \brief Size of FCS in octets. */ +#define PAL_BB_154_FCS_LEN 2 + +/*! \brief FCS initialization value. */ +#define PAL_BB_154_FCS_INIT_VALUE 0x0000 + +/*! \brief Frame control bits and fields. */ +#define PAL_BB_154_FC_FRAME_TYPE_SHIFT 0 +#define PAL_BB_154_FC_FRAME_TYPE_MASK 0x0007 /*!< Bitmask. */ +#define PAL_BB_154_FC_FRAME_TYPE_CD_MASK 0x0001 /*!< Convenient way of checking if MAC command or data. */ +#define PAL_BB_154_FC_FRAME_TYPE_CMD_MASK 0x0003 /*!< Convenient way of checking if MAC command. */ +#define PAL_BB_154_FC_FRAME_TYPE(x) (((x) & PAL_BB_154_FC_FRAME_TYPE_MASK)/*>> PAL_BB_154_FC_FRAME_TYPE_SHIFT*/) /*!< Optimized bit 0. */ + +#define PAL_BB_154_FC_SECURITY_ENABLED_SHIFT 3 +#define PAL_BB_154_FC_SECURITY_ENABLED_MASK 0x0008 +#define PAL_BB_154_FC_SECURITY_ENABLED(x) (((x) & PAL_BB_154_FC_SECURITY_ENABLED_MASK) >> PAL_BB_154_FC_SECURITY_ENABLED_SHIFT) + +#define PAL_BB_154_FC_FRAME_PENDING_SHIFT 4 +#define PAL_BB_154_FC_FRAME_PENDING_MASK 0x0010 +#define PAL_BB_154_FC_FRAME_PENDING(x) (((x) & PAL_BB_154_FC_FRAME_PENDING_MASK) >> PAL_BB_154_FC_FRAME_PENDING_SHIFT) + +#define PAL_BB_154_FC_ACK_REQUEST_SHIFT 5 +#define PAL_BB_154_FC_ACK_REQUEST_MASK 0x0020 +#define PAL_BB_154_FC_ACK_REQUEST(x) (((x) & PAL_BB_154_FC_ACK_REQUEST_MASK) >> PAL_BB_154_FC_ACK_REQUEST_SHIFT) + +#define PAL_BB_154_FC_PAN_ID_COMP_SHIFT 6 +#define PAL_BB_154_FC_PAN_ID_COMP_MASK 0x0040 +#define PAL_BB_154_FC_PAN_ID_COMP(x) (((x) & PAL_BB_154_FC_PAN_ID_COMP_MASK) >> PAL_BB_154_FC_PAN_ID_COMP_SHIFT) + +#define PAL_BB_154_FC_DST_ADDR_MODE_SHIFT 10 +#define PAL_BB_154_FC_DST_ADDR_MODE_MASK 0x0C00 +#define PAL_BB_154_FC_DST_ADDR_MODE(x) (((x) & PAL_BB_154_FC_DST_ADDR_MODE_MASK) >> PAL_BB_154_FC_DST_ADDR_MODE_SHIFT) + +#define PAL_BB_154_FC_FRAME_VERSION_SHIFT 12 +#define PAL_BB_154_FC_FRAME_VERSION_MASK 0x3000 +#define PAL_BB_154_FC_FRAME_VERSION(x) (((x) & PAL_BB_154_FC_FRAME_VERSION_MASK) >> PAL_BB_154_FC_FRAME_VERSION_SHIFT) + +#define PAL_BB_154_FC_SRC_ADDR_MODE_SHIFT 14 +#define PAL_BB_154_FC_SRC_ADDR_MODE_MASK 0xC000 +#define PAL_BB_154_FC_SRC_ADDR_MODE(x) (((x) & PAL_BB_154_FC_SRC_ADDR_MODE_MASK) >> PAL_BB_154_FC_SRC_ADDR_MODE_SHIFT) + +/*! \brief Mask for checking legacy security */ +#define PAL_BB_154_FC_LEGACY_SEC_TEST(x) (((x) & (PAL_BB_154_FC_SECURITY_ENABLED_MASK | PAL_BB_154_FC_FRAME_VERSION_MASK)) == PAL_BB_154_FC_SECURITY_ENABLED_MASK) + +/*! \brief Mask for checking frame pending processing based on ack. requested and being a MAC command frame */ +#define PAL_BB_154_FC_FRAME_TYPE_FP_TEST (PAL_BB_154_FC_ACK_REQUEST_MASK | PAL_BB_154_FC_FRAME_TYPE_CMD_MASK) + +/*! \brief Mask for checking ack. sending based on ack. requested and being a MAC command or data frame */ +#define PAL_BB_154_FC_FRAME_TYPE_ACK_TEST (PAL_BB_154_FC_ACK_REQUEST_MASK | PAL_BB_154_FC_FRAME_TYPE_CD_MASK) + +#define PAL_BB_154_SCAN_MAX_PD_ENTRIES 16 /*!< Note - arbitrary number and could make it easy by sending all beacons using beacon notify indication. */ +#define PAL_BB_154_SCAN_MAX_ED_ENTRIES 16 /*!< Note - can't have more than 16 for 2.4GHz. */ + +/************************************************************************************************** + PHY definitions +**************************************************************************************************/ + +/*! \brief Symbol duration in microseconds (2450 MHz O-QPSK). */ +#define PAL_BB_154_SYMBOL_DURATION 16 + +/*! \brief ED duration in symbols (802.15.4-2006 6.9.7). */ +#define PAL_BB_154_ED_DURATION 8 + +/*! \brief The number of symbols per octets for the current PHY (2450 MHz O-QPSK). */ +#define PAL_BB_154_SYMBOLS_PER_OCTET 2 + +/************************************************************************************************** + Preamble field length + 802.15.4-2006 Table 19 +**************************************************************************************************/ + +/*! \brief Preamble field length in symbols (2450 MHz O-QPSK). */ +#define PAL_BB_154_PREAMBLE_FIELD_LENGTH 8 + +/*! \brief SFD field length in symbols (2450 MHz O-QPSK). */ +#define PAL_BB_154_SFD_FIELD_LENGTH 2 + +/************************************************************************************************** + PHY constants + 802.15.4-2006 Table 22 +**************************************************************************************************/ + +/*! \brief The maximum PSDU size (in octets) the PHY shall be able to receive. */ +#define PAL_BB_154_aMaxPHYPacketSize 127 + +/*! \brief RX-to-TX or TX-to-RX maximum turnaround time (in symbol periods). */ +#define PAL_BB_154_aTurnaroundTime 12 + +/************************************************************************************************** + MAC sublayer constants + 802.15.4-2006 Table 85 +**************************************************************************************************/ + +/*! \brief SHR duration for 802.15.4-2006. (2.4GHz PHY) */ +#define PAL_BB_154_phySHRDuration 10 + +/*! \brief Symbols per octet for 802.15.4-2006. (2.4GHz PHY) */ +#define PAL_BB_154_phySymbolsPerOctet 2 + +/*! \brief The number of symbols forming a superframe slot when the superframe order is equal to 0. */ +#define PAL_BB_154_aBaseSlotDuration 60 + +/*! \brief The number of symbols forming a superframe when the superframe order is equal to 0. */ +#define PAL_BB_154_aBaseSuperframeDuration (PAL_BB_154_aBaseSlotDuration * PAL_BB_154_aNumSuperframeSlots) + +/* PAL_BB_154_aExtendedAddress Now a vendor-specific PIB attribute */ + +/*! \brief The number of superframes in which a GTS descriptor exists in the beacon frame of the PAN + * coordinator. */ +#define PAL_BB_154_aGTSDescPersistenceTime 4 + +/*! \brief The maximum number of octets added by the MAC sublayer to the MAC payload of a beacon frame. */ +#define PAL_BB_154_aMaxBeaconOverhead 75 + +/*! \brief The maximum beacon payload length. */ +#define PAL_BB_154_aMaxBeaconPayloadLength (PAL_BB_154_aMaxPHYPacketSize - PAL_BB_154_aMaxBeaconOverhead) + +/*! \brief The number of consecutive lost beacons that will cause the MAC sublayer of a receiving device + * to declare a loss of synchronization. */ +#define PAL_BB_154_aMaxLostBeacons 4 + +/*! \brief The maximum number of octets added by the MAC sublayer to the PSDU without security. */ +#define PAL_BB_154_aMaxMPDUUnsecuredOverhead 25 + +/*! \brief The maximum size of an MPDU, in octets, that can be followed by a SIFS period. */ +#define PAL_BB_154_aMaxSIFSFrameSize 18 + +/*! \brief The minimum number of symbols forming the CAP. + * This ensures that MAC commands can still be + * transferred to devices when GTSs are being used. An exception to this minimum shall be allowed + * for the accommodation of the temporary increase in the beacon frame length needed to perform GTS + * maintenance. */ +#define PAL_BB_154_aMinCAPLength 440 + +/*! \brief The minimum number of octets added by the MAC sublayer to the PSDU. */ +#define PAL_BB_154_aMinMPDUOverhead 9 + +/*! \brief The number of slots contained in any superframe. */ +#define PAL_BB_154_aNumSuperframeSlots 16 + +/*! \brief The number of symbols forming the basic time period used by the CSMA-CA algorithm. */ +#define PAL_BB_154_aUnitBackoffPeriod 20 + +#define PAL_BB_154_RX_ACK_TIMEOUT_SYMB PAL_BB_154_aUnitBackoffPeriod + \ + PAL_BB_154_aTurnaroundTime + \ + PAL_BB_154_phySHRDuration + \ + (6 * PAL_BB_154_phySymbolsPerOctet) + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief 802.15.4 channelization parameters. */ +typedef struct +{ + uint8_t channel; /*!< Channel. */ + int8_t txPower; /*!< Transmit power, units dBm. */ +} PalBb154Chan_t; + +/*! \brief Transmit complete ISR callback signature. */ +typedef void (*PalBb154TxIsr_t)(uint8_t flags); + +/*! \brief Frame pending check callback. */ +typedef bool_t (*PalBb154FPIsr_t)(uint8_t srcAddrMode, uint64_t srcAddr); + +/*! \brief Receive complete ISR callback signature. */ +typedef uint8_t (*PalBb154RxIsr_t)(uint8_t *pBuf, uint16_t len, int8_t rssi, uint32_t timestamp, uint8_t flags); + +/*! \brief CCA or energy detect complete ISR callback signature. */ +typedef void (*PalBb154EdIsr_t)(int8_t rssi); + +/*! \brief Driver error callback signature. */ +typedef void (*PalBb154Err_t)(uint8_t status); + +/*! \brief Buffer free callback signature. */ +typedef void *(*PalBb154Alloc_t)(uint16_t len); + +/*! \brief Buffer free callback signature. */ +typedef void (*PalBb154Free_t)(void *pBuf); + +/*! \brief Operation parameters. */ +typedef struct +{ + uint8_t flags; /*!< Baseband driver operation flags. */ + PalBb154TxIsr_t txCback; /*!< Transmit complete ISR callback. */ + PalBb154FPIsr_t fpCback; /*!< Frame pending check callback. */ + PalBb154RxIsr_t rxCback; /*!< Receive complete ISR callback. */ + PalBb154EdIsr_t edCback; /*!< ED complete ISR callback. */ + PalBb154Err_t errCback; /*!< Error callback. */ +} PalBb154OpParam_t; + +/*! \brief Transmit buffer descriptor. */ /* Note - must be packed so buffer immediately follows length */ +typedef struct PalBb154TxBufDesc +{ + uint8_t pad[2]; /*!< Padding to make structure uint32 aligned */ + uint8_t handle; /*!< Handle used for data frames only */ + uint8_t len; /*!< Length of frame, which is concatenated to this header */ +} PalBb154TxBufDesc_t; + +/*! \brief PAL_BB_154_TX_FRAME_PTR */ +#define PAL_BB_154_TX_FRAME_PTR(x) ((uint8_t *)(((PalBb154TxBufDesc_t *)(x))+1)) + +/*! \brief Baseband driver statistics. */ +typedef struct +{ + uint32_t txSchMiss; /*!< Number of missed Rx. */ + uint32_t rxSchMiss; /*!< Number of missed Tx. */ + uint32_t txPkt; /*!< Number of successful Tx. */ + uint32_t txDmaFail; /*!< Number of Tx DMA failures. */ + uint32_t rxPkt; /*!< Number of successful Rx. */ + uint32_t rxPktTimeout; /*!< Number of Rx timeouts. */ + uint32_t rxFilterFail; /*!< Number of Rx filter failures. */ + uint32_t rxCrcFail; /*!< Number of CRC failures. */ + uint32_t rxDmaFail; /*!< Number of Rx DMA failures. */ + uint32_t edReq; /*!< Number of ED requests. */ + uint32_t ed; /*!< Number of successful ED. */ + uint32_t edSchMiss; /*!< Number of missed ED. */ + uint32_t ccaSchMiss; /*!< Number of missed CCA. */ + uint32_t txReq; /*!< Number of Tx requests. */ + uint32_t rxReq; /*!< Number of Rx requests. */ +} PalBb154DrvStats_t; + +/*! \brief MAC PIB for driver. */ +typedef struct PalBb154DrvPib_tag +{ + uint64_t extAddr; /* Vendor-specific PIB attribute */ + uint16_t vsCRCOverride; /* Vendor-specific PIB attribute */ + uint16_t panId; + uint16_t shortAddr; + uint8_t deviceType; /* Vendor-specific PIB attribute */ + uint8_t disableCCA; /* Vendor-specific PIB attribute */ + uint8_t minBE; + uint8_t maxBE; + uint8_t maxCSMABackoffs; + uint8_t maxFrameRetries; + uint8_t promiscuousMode; + uint8_t rxEnabled; + uint8_t rxOnWhenIdle; +} PalBb154DrvPib_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Initialize the 802.15.4 baseband driver. + * + * One-time initialization of baseband resources. This routine can be used to setup software + * driver resources, load RF trim parameters and execute RF calibrations. + * + * This routine should block until the BB hardware is completely initialized. + */ +/*************************************************************************************************/ +void PalBb154Init(void); + +/*************************************************************************************************/ +/*! + * \brief Register callbacks for the 802.15.4 baseband driver. + */ +/*************************************************************************************************/ +void PalBb154Register(PalBb154Alloc_t allocCback, PalBb154Free_t freeCback); + +/*************************************************************************************************/ +/*! + * \brief Enable the BB hardware. + * + * This routine brings the BB hardware out of low power (enable power and clocks). This routine is + * called just before a 802.15.4 BOD is executed. + */ +/*************************************************************************************************/ +void PalBb154Enable(void); + +/*************************************************************************************************/ +/*! + * \brief Disable the BB hardware. + * + * This routine signals the BB hardware to go into low power (disable power and clocks). This + * routine is called after all 802.15.4 operations are disabled. + */ +/*************************************************************************************************/ +void PalBb154Disable(void); + +/*************************************************************************************************/ +/*! + * \brief Set channelization parameters. + * + * \param pParam Channelization parameters. + * + * Calling this routine will set parameters for all future transmit, receive, and energy detect + * operations until this routine is called again providing new parameters. + * + * \note \a pParam is not guaranteed to be static and is only valid in the context of the + * call to this routine. Therefore parameters requiring persistence should be copied. + */ +/*************************************************************************************************/ +void PalBb154SetChannelParam(const PalBb154Chan_t *pParam); + +/*************************************************************************************************/ +/*! + * \brief Reset channelization parameters. + * + * Calling this routine will reset (clear) the channelization parameters. + */ +/*************************************************************************************************/ +void PalBb154ResetChannelParam(void); + +/*************************************************************************************************/ +/*! + * \brief Set the operation parameters. + * + * \param pOpParam Operations parameters. + * + * Calling this routine will set parameters for all future transmit, receive, ED, and CCA + * operations until this routine is called again providing new parameters. + * + * \note \a pOpParam is not guaranteed to be static and is only valid in the context of the + * call to this routine. Therefore parameters requiring persistence should be copied. + */ +/*************************************************************************************************/ +void PalBb154SetOpParams(const PalBb154OpParam_t *pOpParam); + +/*************************************************************************************************/ +/*! + * \brief Get Driver PIB. + * + * \return Driver PIB pointer. + * + * Calling this routine retun a pointer to the driver PIB. + */ +/*************************************************************************************************/ +PalBb154DrvPib_t *PalBb154GetDrvPIB(void); + +/*************************************************************************************************/ +/*! + * \brief Flushes PIB attributes to hardware. + * + * Calling this routine will flush all PIB attributes that have a hardware counterpart to the + * respective registers in hardware. + */ +/*************************************************************************************************/ +void PalBb154FlushPIB(void); + +/*************************************************************************************************/ +/*! + * \brief Clear all received buffers (active and queued). + * + * Calling this routine will clear and free the active receive buffer (if any) and all queued + * receive buffers. This should only be called when the operation is terminating. + */ +/*************************************************************************************************/ +void PalBb154ClearRxBufs(void); + +/*************************************************************************************************/ +/*! + * \brief Reclaim the buffer associated with the received frame. + * + * \param pRxFrame Pointer to the received frame. + * + * \return Total number of receive buffers queued. + * + * Calling this routine will put the buffer associated with the received frame back onto the + * receive queue. Note the actual buffer pointer may not be the same as the frame pointer + * dependent on driver implementation. If the queue is empty when the driver expects to + * transition to the receive state, the driver will instead move into the off state. + */ +/*************************************************************************************************/ +uint8_t PalBb154ReclaimRxFrame(uint8_t *pRxFrame); + +/*************************************************************************************************/ +/*! + * \brief Build receive buffer queue + * + * \param len Length of each receive buffer. + * \param num Number of buffers to load into the queue. + */ +/*************************************************************************************************/ +void PalBb154BuildRxBufQueue(uint8_t num); + +/*************************************************************************************************/ +/*! + * \brief Get payload pointer. + * + * \param pFrame Frame buffer pointing to first octet of frame + * \param fctl Frame control field + * + * \return Pointer to frame payload or NULL if illegal addr mode combo. + * + * Obtains the source and destination addresses from the frame. If either parameter is NULL, + * simply skips past the fields + */ +/*************************************************************************************************/ +uint8_t *PalBb154GetPayloadPtr(uint8_t *pFrame, uint16_t fctl); + +/*************************************************************************************************/ +/*! + * \brief Transmit a packet. + * + * \param pDesc Chain of transmit buffer descriptors. + * \param cnt Number of descriptors. + * \param due Due time for transmit (if \a now is FALSE). + * \param now TRUE if packet should be transmitted with minimal delay. + */ +/*************************************************************************************************/ +void PalBb154Tx(PalBb154TxBufDesc_t *pDesc, uint8_t cnt, uint32_t due, bool_t now); + +/*************************************************************************************************/ +/*! + * \brief Receive a packet. + * + * \param due Due time for receive (if \a now is FALSE). + * \param now TRUE if packet should be received with minimal delay. + * \param timeout Timeout. + */ +/*************************************************************************************************/ +void PalBb154Rx(uint32_t due, bool_t now, uint32_t timeout); + +/*************************************************************************************************/ +/*! + * \brief Perform energy detect. + * + * \param due Due time for energy detect (if \a now is FALSE). + * \param now TRUE if energy detect should occur minimal delay. + * + * Perform energy detect and return energy level to assess channel status. + */ +/*************************************************************************************************/ +void PalBb154Ed(uint32_t due, bool_t now); + +/*************************************************************************************************/ +/*! + * \brief Cancel any pending operation. + * + * \return TRUE if pending operation could be cancelled. + * + * Cancel any pending operation. + */ +/*************************************************************************************************/ +bool_t PalBb154Off(void); + +/*************************************************************************************************/ +/*! + * \brief Convert RSSI to LQI. + * + * \return LQI value. + * + * Converts RSSI value into equivalent LQI value from 0 to 0xFF. + */ +/*************************************************************************************************/ +uint8_t PalBb154RssiToLqi(int8_t rssi); + +/*************************************************************************************************/ +/*! + * \brief Return the last received RSSI. + * + * \param pBuf Storage for results -- first element is integer dBm, second is fractional + */ +/*************************************************************************************************/ +void PalBb154GetLastRssi(uint8_t *pBuf); + +/*************************************************************************************************/ +/*! + * \brief Enter Continuous Transmit mode. + * + * \param rfChan Physical channel number + * \param modulation Modulation type (0 disables) + * \param txPhy PHY type + * \param power Pransmit power (dBm) + */ +/*************************************************************************************************/ +void PalBb154ContinuousTx(uint8_t rfChan, uint8_t modulation, uint8_t txPhy, int8_t power); + +/*************************************************************************************************/ +/*! + * \brief Enter Continuous Receive mode. + * + * \param rfChan Physical channel number + * \param rxPhy PHY type + */ +/*************************************************************************************************/ +void PalBb154ContinuousRx(uint8_t rfChan, uint8_t rxPhy); + +/*************************************************************************************************/ +/*! + * \brief Stop Continous Transmit or Receive mode. + */ +/*************************************************************************************************/ +void PalBb154ContinuousStop(void); + +/*************************************************************************************************/ +/*! + * \brief Get baseband driver statistics. + * + * \param pStats Storage for statistics. + */ +/*************************************************************************************************/ +void PalBb154DrvGetStats(PalBb154DrvStats_t *pStats); + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_BB_154_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble.h index bbf90276e20..074c9492b16 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble.h @@ -1,31 +1,32 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief BLE Baseband interface file. + * \file + * + * \brief BLE Baseband interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_BB_BLE_H #define PAL_BB_BLE_H -#include "stack/platform/include/pal_bb.h" -#include "stack/platform/include/pal_crypto.h" -#include "stack/platform/include/pal_types.h" +#include "pal_bb.h" +#include "pal_crypto.h" #ifdef __cplusplus extern "C" { @@ -47,8 +48,8 @@ extern "C" { enum { PAL_BB_NONCE_MODE_PKT_CNTR, /*!< Packet counter mode (default). */ - PAL_BB_NONCE_MODE_CIS_CNTR, /*!< CIS counter mode, PalCryptoEnc_t::pTxPktCounter/pRxPktCounter must be non-NULL. */ - PAL_BB_NONCE_MODE_EVT_CNTR /*!< Event counter mode, PalCryptoEnc_t::pEventCounter must be non-NULL. */ + PAL_BB_NONCE_MODE_EXT16_CNTR, /*!< 16-bit counter mode, PalCryptoEnc_t::pEventCounter must be non-NULL. */ + PAL_BB_NONCE_MODE_EXT64_CNTR /*!< 64-bit counter mode, PalCryptoEnc_t::pTxPktCounter/pRxPktCounter must be non-NULL. */ }; /*! \brief Connection type. */ @@ -65,24 +66,25 @@ enum /*! \brief BLE channelization parameters. */ typedef struct { - uint8_t opType; /*!< Operation type. */ - uint8_t chanIdx; /*!< Channel index. */ - int8_t txPower; /*!< Transmit power, unit is dBm. */ - uint32_t accAddr; /*!< Access address. */ - uint32_t crcInit; /*!< CRC initialization value. */ - uint8_t txPhy; /*!< Transmitter PHY. */ - uint8_t rxPhy; /*!< Receiver PHY. */ - uint8_t initTxPhyOptions; /*!< Initial Tx PHY options. */ - uint8_t tifsTxPhyOptions; /*!< TIFS Tx PHY options. */ - bool_t peerTxStableModIdx; /*!< Peer uses stable modulation index on transmitter. */ - bool_t peerRxStableModIdx; /*!< Peer uses stable modulation index on receiver. */ - PalCryptoEnc_t enc; /*!< Encryption parameters (NULL if disabled). */ + uint8_t opType; /*!< Operation type. */ + uint8_t chanIdx; /*!< Channel index. */ + int8_t txPower; /*!< Active transmit power, unit is dBm. */ + uint32_t accAddr; /*!< Access address. */ + uint32_t crcInit; /*!< CRC initialization value. */ + uint8_t txPhy; /*!< Transmitter PHY. */ + uint8_t rxPhy; /*!< Receiver PHY. */ + uint8_t initTxPhyOptions; /*!< Initial Tx PHY options. */ + uint8_t tifsTxPhyOptions; /*!< TIFS Tx PHY options. */ + bool_t peerTxStableModIdx; /*!< Peer uses stable modulation index on transmitter. */ + bool_t peerRxStableModIdx; /*!< Peer uses stable modulation index on receiver. */ + PalCryptoEnc_t enc; /*!< Encryption parameters (NULL if disabled). */ #if (LL_ENABLE_TESTER) - uint32_t accAddrRx; /*!< Access address override for receptions. */ - uint32_t accAddrTx; /*!< Access address override for transmissions. */ - uint32_t crcInitRx; /*!< CRC initialization override for receptions. */ - uint32_t crcInitTx; /*!< CRC initialization override for transmissions. */ + uint32_t accAddrRx; /*!< Access address override for receptions. */ + uint32_t accAddrTx; /*!< Access address override for transmissions. */ + uint32_t crcInitRx; /*!< CRC initialization override for receptions. */ + uint32_t crcInitTx; /*!< CRC initialization override for transmissions. */ + int8_t txPwrOffset; /*!< override offset for txPower. */ #endif } PalBbBleChan_t; @@ -99,22 +101,30 @@ typedef void (*PalBbBleTxIsr_t)(uint8_t status); /*! \brief Receive complete ISR callback signature. */ typedef void (*PalBbBleRxIsr_t)(uint8_t status, int8_t rssi, uint32_t crc, uint32_t timestamp, uint8_t rxPhyOptions); +/*! \brief IFS modes. */ +typedef enum +{ + PAL_BB_IFS_MODE_CLR, /*!< Clear IFS (last packet). */ + PAL_BB_IFS_MODE_TOGGLE_TIFS, /*!< Toggle operation with TIFS timing. */ + PAL_BB_IFS_MODE_SAME_ABS /*!< Same operation with absolute timing. */ +} PalBbIfsMode_t; + /*! \brief BLE data transfer parameters. */ typedef struct { PalBbBleTxIsr_t txCback; /*!< Transmit completion callback. */ PalBbBleRxIsr_t rxCback; /*!< Receive completion callback. */ - uint32_t due; /*!< Due time of the first packet. */ + uint32_t dueUsec; /*!< Due time of the first packet in microseconds. */ uint32_t rxTimeoutUsec; /*!< Receive timeout in microseconds. */ - uint16_t dueOffsetUsec; /*!< Due time offset in microseconds. */ } PalBbBleDataParam_t; /*! \brief Operation parameters. */ typedef struct { - bool_t ifsSetup; /*!< TRUE if IFS timer should be set up for next operation. */ - uint16_t ifsUsec; /*!< IFS time in microseconds. */ + PalBbIfsMode_t ifsMode:8; /*!< IFS mode for next operation. */ + uint32_t ifsTime; /*!< Absolute time of next PDU. */ + PalBbBleChan_t *pIfsChan; /*!< Channel of next PDU, NULL for no change. */ } PalBbBleOpParam_t; /*! \brief Transmit buffer descriptor. */ @@ -140,8 +150,6 @@ typedef struct /*! * \brief Initialize the BLE baseband driver. * - * \return None. - * * One-time initialization of BLE baseband driver. */ /*************************************************************************************************/ @@ -151,8 +159,6 @@ void PalBbBleInit(void); /*! * \brief Enable the BB hardware. * - * \return None. - * * Wake the BB hardware out of sleep and enable for operation. All BB functionality is * available when this routine completes. BB clock is set to zero and started. */ @@ -163,8 +169,6 @@ void PalBbBleEnable(void); /*! * \brief Disable the BB hardware. * - * \return None. - * * Disable the baseband and put radio hardware to sleep. Must be called from an idle state. * A radio operation cannot be in progress. */ @@ -184,8 +188,6 @@ void PalBbBleDisable(void); * * \param pChan Channelization parameters. * - * \return None. - * * Calling this routine will set parameters for all future transmit and receive operations * until this routine is called again providing new parameters. * @@ -213,8 +215,6 @@ void PalBbBleSetChannelParam(PalBbBleChan_t *pChan); * * \param pParam Data exchange parameters. * - * \return None. - * * Calling this routine will set parameters for all future transmit and receive operations * until this routine is called again providing new parameters. */ @@ -227,8 +227,6 @@ void PalBbBleSetDataParams(const PalBbBleDataParam_t *pParam); * * \param pOpParam Operations parameters. * - * \return None. - * * Calling this routine will set parameters for the next transmit or receive operations. */ /*************************************************************************************************/ @@ -241,8 +239,6 @@ void PalBbBleSetOpParams(const PalBbBleOpParam_t *pOpParam); * \param descs Array of transmit buffer descriptors. * \param cnt Number of descriptors. * - * \return None. - * * Set the first data buffer for the first packet of an alternating Tx-Rx data exchange cycle. */ /*************************************************************************************************/ @@ -255,8 +251,6 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt); * \param descs Array of transmit buffer descriptor. * \param cnt Number of descriptors. * - * \return None. - * * If possible, the transmit will occur at the TIFS timing. If not possible, the callback status * will indicate this. */ @@ -270,8 +264,6 @@ void PalBbBleTxTifsData(PalBbBleTxBufDesc_t descs[], uint8_t cnt); * \param pBuf Receive data buffer. * \param len Length of data buffer. * - * \return None. - * * Set the first data buffer for the first packet of an alternating Rx-Tx data exchange cycle. */ /*************************************************************************************************/ @@ -284,8 +276,6 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len); * \param pBuf Receive data buffer. * \param len Length of data buffer. * - * \return None. - * * If possible, the receive will occur on the TIFS timing. If not possible, the callback status * will indicate this. */ @@ -296,8 +286,6 @@ void PalBbBleRxTifsData(uint8_t *pBuf, uint16_t len); /*! * \brief Cancel TIFS timer. * - * \return None. - * * This stops any active TIFS timer operation. This routine is always called in the callback * (i.e. ISR) context. */ @@ -308,8 +296,6 @@ void PalBbBleCancelTifs(void); /*! * \brief Cancel a pending transmit or receive. * - * \return None. - * * This stops any active radio operation. This routine is never called in the callback * (i.e. ISR) context. */ @@ -329,8 +315,6 @@ void PalBbBleCancelData(void); * * \param enable Flag to indicate data whitening. * - * \return None. - * * Sets an internal variable that indicates if data whitening is enabled or not. */ /*************************************************************************************************/ @@ -342,8 +326,6 @@ void PalBbBleEnableDataWhitening(bool_t enable); * * \param enable Flag to indicate PRBS15. * - * \return None. - * * Immediately enable or disable continuous PRBS15 bitstream. Setting the channelization * parameters with \a PalBbBleSetChannelParam() must precede enabling PRBS15. * @@ -358,8 +340,6 @@ void PalBbBleEnablePrbs15(bool_t enable); * * \param dir 0=slave, non-zero=master * - * \return None. - * */ /*************************************************************************************************/ void PalBbBleInlineEncryptDecryptSetDirection(uint8_t dir); @@ -370,12 +350,19 @@ void PalBbBleInlineEncryptDecryptSetDirection(uint8_t dir); * * \param count Packet counter value, a 39-bit value * - * \return None. - * */ /*************************************************************************************************/ void PalBbBleInlineEncryptSetPacketCount(uint64_t count); +/*************************************************************************************************/ +/*! + * \brief Low power operation. + * + * \note Called by upper baseband code. + */ +/*************************************************************************************************/ +void PalBbBleLowPower(void); + /*! \} */ /* PAL_BB_BLE_TEST */ #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble_tester.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble_tester.h index 180ebafaf52..543e628b0b0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble_tester.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_bb_ble_tester.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief BLE Baseband tester interface file. + * \file + * + * \brief BLE Baseband tester interface file. + * + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_BB_BLE_TESTER_H #define PAL_BB_BLE_TESTER_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" /************************************************************************************************** Function Declarations @@ -35,13 +37,20 @@ * * \param enable If TRUE enable bypass PDU filtering, FALSE otherwise. * - * \return None. - * * Enable bypassing PDU filtering. */ /*************************************************************************************************/ void PalBbTesterEnablePduFilterBypass(bool_t enable); +/*************************************************************************************************/ +/*! + * \brief Invalidate next access address. + * + * \param forRx For Rx or Tx boolean. + */ +/*************************************************************************************************/ +void PalBbTesterInvalidateNextAccAddr(bool_t forRx); + /*************************************************************************************************/ /*! * \brief Invalidate access address value. @@ -51,8 +60,6 @@ void PalBbTesterEnablePduFilterBypass(bool_t enable); * \param shiftMask TRUE if corrupting AA by one bit and corrupted bit location is shifted every TX/RX. * \param forRx TRUE for Rx, FALSE for Tx. * - * \return None. - * * Force the receiver to receive a miss a packet if the receive channel is in * \b chanMask while stepping through the invalid pattern in \b invalidMask. */ @@ -67,8 +74,6 @@ void PalBbTesterSetInvalidAccessAddress(uint64_t chanMask, uint32_t invalidMask, * \param adjMask Number of adjustments (0 to disable). * \param forRx TRUE for Rx, FALSE for Tx. * - * \return None. - * * Force the receiver to receive a packet with CRC error if the receive channel is in * \b chanMask while stepping through the invalid pattern in \b invalidMask. */ @@ -82,8 +87,6 @@ void PalBbTesterSetInvalidCrcInit(uint64_t chanMask, uint32_t adjMask, bool_t fo * \param hdrMask Header mask. * \param hdrValue Match value. * - * \return None. - * * Modify the transmit channel parameters of a packet only when the Tx packet header matches * the given parameters. This applies to the modification parameter provided by the following * routines: @@ -100,8 +103,6 @@ void PalBbTesterSetModifyTxPktTrigger(uint16_t hdrMask, uint16_t hdrValue); * * \param adjNs Adjustment value in nanoseconds. * - * \return None. - * * Adjust the TIFS timing of transmit by the given signed value of timer ticks. * If adjustment value is out of range, maximum allowed value is used. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_btn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_btn.h index c10fbd2db41..4000dd77d54 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_btn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_btn.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Button driver definition. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Button driver definition. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_BTN_H #define PAL_BTN_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -36,27 +38,47 @@ extern "C" { Data Types **************************************************************************************************/ -/*! \brief Button state. */ +/*! \brief Operational states. */ typedef enum { - PAL_BTN_STATE_UP, /*!< Button is released. */ - PAL_BTN_STATE_DOWN, /*!< Button is pressed. */ + PAL_BTN_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_BTN_STATE_ERROR = 0, /*!< Error state. */ + PAL_BTN_STATE_READY /*!< Ready state. */ } PalBtnState_t; -/*! \brief Action callback. This may be returned in interrupt context. */ -typedef void (*PalBtnActionCback_t)(uint8_t btnId, PalBtnState_t state); +/*! \brief Button position. */ +typedef enum +{ + PAL_BTN_POS_INVALID, /*!< Button position is invalid. */ + PAL_BTN_POS_DOWN, /*!< Button position is depressed. */ + PAL_BTN_POS_UP /*!< Button position is released. */ +} PalBtnPos_t; + +/*! \brief Action callback signature. */ +typedef void (*PalBtnActionCback_t)(uint8_t btnId, PalBtnPos_t state); + +/*! \brief Audio button assignments (only mapped in audio applications). */ +enum +{ + PAL_BTN_AUDIO_PLAY = 0x80, /*!< Play button. */ + PAL_BTN_AUDIO_FWD, /*!< Fast Forward button. */ + PAL_BTN_AUDIO_RWD, /*!< Fast Rewind button. */ + PAL_BTN_AUDIO_VOL_UP, /*!< Volume Up button. */ + PAL_BTN_AUDIO_VOL_DN, /*!< Volume Down button. */ + PAL_BTN_AUDIO_MUTE /*!< Mute button. */ +}; /************************************************************************************************** Function Declarations **************************************************************************************************/ /* Initialization */ -void PalBtnInit(void); +void PalBtnInit(PalBtnActionCback_t actCback); void PalBtnDeInit(void); -void PalBtnRegister(PalBtnActionCback_t actCback); /* Control and Status */ -PalBtnState_t PalBtnGetState(uint8_t id); +PalBtnState_t PalBtnGetState(void); +PalBtnPos_t PalBtnGetPosition(uint8_t id); /*! \} */ /* PAL_BUTTON */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_cfg.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_cfg.h index ac764556c64..4aaea0e7a33 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_cfg.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_cfg.h @@ -1,29 +1,31 @@ - /* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 + /*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief System configuration definition. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief System configuration definition. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_CFG_H #define PAL_CFG_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -49,7 +51,7 @@ typedef enum /************************************************************************************************** Function Declarations **************************************************************************************************/ -void PalCfgLoadData(uint8_t cfgId, uint8_t *pBuf, uint32_t len); +void PalCfgLoadData(uint8_t cfgId, void *pBuf, uint32_t len); void PalCfgSetDeviceUuid(uint8_t *pBuf); /*! \} */ /* PAL_CFG */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_codec.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_codec.h new file mode 100644 index 00000000000..f387f57a10e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_codec.h @@ -0,0 +1,123 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Hardware audio codec interface file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_CODEC_H +#define PAL_CODEC_H + +#include "wsf_types.h" +#include "wsf_os.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \addtogroup PAL_CODEC + * \{ + */ + +/**************************************************************************************************' + Data Types +**************************************************************************************************/ + +/*! \brief Audio data path direction. */ +typedef enum +{ + PAL_CODEC_DIR_INPUT = 0, /*!< Input data path. */ + PAL_CODEC_DIR_OUTPUT = 1 /*!< Output data path. */ +} PalAudioDir_t; + +/*! \brief Audio Channel. */ +typedef enum +{ + PAL_CODEC_CH_LEFT = 0, /*!< Left channel. */ + PAL_CODEC_CH_RIGHT = 1, /*!< Right channel. */ + AUDIO_NUM_CH /*!< Right channel. */ +} PalAudioChan_t; + +/*! \brief Audio Channel mask. */ +enum +{ + PAL_CODEC_CH_LEFT_BIT = (1 << PAL_CODEC_CH_LEFT), + PAL_CODEC_CH_RIGHT_BIT = (1 << PAL_CODEC_CH_RIGHT) +}; + +/*! \brief Standard codec info block. */ +typedef struct +{ + uint8_t codecId; /*!< Codec ID. */ +} AudioStdCodecInfo_t; + +/*! \brief VS codec info block. */ +typedef struct +{ + uint16_t compId; /*!< Company ID. */ + uint16_t codecId; /*!< Codec ID. */ +} AudioVsCodecInfo_t; + +/*! \brief Buffer available call signature. */ +typedef void (*PalCodecDataReady_t)(uint16_t id); + +/*! \brief Codec. */ +typedef struct +{ + PalAudioDir_t dir; /*!< Stream data direction. */ + uint16_t chMask; /*!< Audio channel mask. */ + uint32_t intervalUsec; /*!< SDU interval in microseconds. */ + uint32_t pktCtr; /*!< Initial packet counter value. */ + PalCodecDataReady_t rdyCback; /*!< Data ready callback. */ +} PalCodecSreamParam_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Codec Information */ +void PalCodecReadLocalSupportedCodecs(uint8_t *pNumStd, AudioStdCodecInfo_t stdCodecs[], + uint8_t *pNumVs, AudioVsCodecInfo_t vsCodecs[]); +bool_t PalCodecReadLocalSupportedCodecCapabilities(uint8_t codingFmt, uint16_t compId, uint16_t vsCodecId, PalAudioDir_t dir); +bool_t PalCodecReadLocalSupportedControllerDelay(uint8_t codingFmt, uint16_t compId, uint16_t vsCodecId, PalAudioDir_t dir, + uint32_t *pMinDly, uint32_t *pMaxDly); +bool_t PalCodecConfigureDataPath(PalAudioDir_t dir, uint8_t dataPathId); + +/* Audio Amplifier */ +void PalCodecAmpInit(void); +uint8_t PalCodecAmpGetVol(void); +void PalCodecAmpVolumeUp(void); +void PalCodecAmpVolumeDown(void); +void PalCodecAmpMute(void); +void PalCodecAmpUnmute(void); + +/* Data Path */ +void PalCodecDataInit(void); +bool_t PalCodecDataStartStream(uint16_t id, PalCodecSreamParam_t *pParam); +void PalCodecDataStopStream(uint16_t id); +uint16_t PalCodecDataStreamIn(uint16_t id, uint8_t *pBuf, uint16_t len, uint32_t *pPktCtr); +void PalCodecDataStreamOut(uint16_t id, const uint8_t *pBuf, uint16_t len, uint32_t pktCtr); + +/*! \} */ /* PAL_CODEC */ + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_CODEC_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_crypto.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_crypto.h index ed1aa6a9935..bfecbbb9461 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_crypto.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_crypto.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Crypto driver definition. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Crypto driver definition. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_CRYPTO_H #define PAL_CRYPTO_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -37,7 +39,7 @@ extern "C" { **************************************************************************************************/ /*! \brief AES block size. */ -#define PAL_CRYPTO_AES_BLOCK_SIZE 16 +#define PAL_CRYPTO_AES_BLOCK_SIZE 16 #define PAL_CRYPTO_LL_KEY_LEN 16 /*!< Encryption key length. */ #define PAL_CRYPTO_LL_IV_LEN 8 /*!< Initialization vector length. */ @@ -78,8 +80,8 @@ typedef struct bool_t enaAuth; /*!< Enable authentication. */ uint8_t nonceMode; /*!< Nonce mode. */ uint16_t *pEventCounter; /*!< Connection event counter. */ - uint64_t *pCisTxPktCounter; /*!< CIS Tx packet counter. Set when nonceMode = PAL_BB_NONCE_MODE_CIS_CNTR. */ - uint64_t *pCisRxPktCounter; /*!< CIS Rx packet counter. Set when nonceMode = PAL_BB_NONCE_MODE_CIS_CNTR.*/ + uint64_t *pTxPktCounter; /*!< Tx packet counter. Set when nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR. */ + uint64_t *pRxPktCounter; /*!< Rx packet counter. Set when nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR. */ uint8_t dir; /*!< Direction value. */ uint8_t type; /*!< Type, ACL, CIS, BIS */ void *pEncryptCtx; /*!< Tx/Encryption context. */ @@ -94,7 +96,7 @@ typedef struct void PalCryptoInit(void); void PalCryptoDeInit(void); -/* Key genration */ +/* Key generation */ void PalCryptoGenerateP256KeyPair(const uint8_t *pPrivKey, uint8_t *pPubKey); void PalCryptoGenerateDhKey(const uint8_t *pPubKey, const uint8_t *pPrivKey, uint8_t *pDhKey); bool_t PalCryptoValidatePublicKey(const uint8_t *pPubKey, bool_t generateKey); @@ -110,7 +112,8 @@ void PalCryptoCcmEnc(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pPlainText, /* Crypto AES */ void PalCryptoAesEcb(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn); -void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir); +void PalCryptoAesCmac(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn, uint16_t len); +void PalCryptoAesEnable(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir); bool_t PalCryptoAesCcmEncrypt(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf, uint8_t *pMic); bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf); void PalCryptoSetEncryptPacketCount(PalCryptoEnc_t *pEnc, uint64_t pktCnt); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_flash.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_flash.h new file mode 100644 index 00000000000..46c8e7a76e8 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_flash.h @@ -0,0 +1,78 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief PAL flash driver. + * + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_FLASH_H +#define PAL_FLASH_H + +#include "pal_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup PAL_FLASH + * \{ */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Callback. This may be returned in interrupt context. */ +typedef void (*PalFlashCback_t)(bool_t status); + +/*! \brief Operational states. */ +typedef enum +{ + PAL_FLASH_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_FLASH_STATE_ERROR = 0, /*!< Error state. */ + PAL_FLASH_STATE_READY, /*!< Ready state. */ + PAL_FLASH_STATE_BUSY /*!< Busy state. */ +} PalFlashState_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void PalFlashInit(PalFlashCback_t actCback); +void PalFlashDeInit(void); + +/* Control and Status */ +PalFlashState_t PalNvmGetState(void); +uint32_t PalNvmGetTotalSize(void); +uint32_t PalNvmGetSectorSize(void); + +/* Data Transfer */ +void PalFlashRead(void *pBuf, uint32_t size, uint32_t srcAddr); +void PalFlashWrite(void *pBuf, uint32_t size, uint32_t dstAddr); +void PalFlashEraseSector(uint32_t size, uint32_t startAddr); +void PalFlashEraseChip(void); + +/*! \} */ /* PAL_FLASH */ + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_FLASH_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_i2s.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_i2s.h new file mode 100644 index 00000000000..f1748ebe7a4 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_i2s.h @@ -0,0 +1,102 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief I2S driver definition. + * + * Copyright (c) 2019 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_I2S_H +#define PAL_I2S_H + +#include "pal_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup PAL_I2S + * \{ */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Operational states. */ +typedef enum +{ + PAL_I2S_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_I2S_STATE_ERROR = 0, /*!< Error state. */ + PAL_I2S_STATE_IDLE, /*!< Initialized state. */ + PAL_I2S_STATE_READY, /*!< Configured state. */ + PAL_I2S_STATE_BUSY /*!< Busy state. */ +} PalI2sState_t; + +/*! \brief Call signature for next buffer pointer. */ +typedef void (*PalI2sCompCback_t)(void *); + +/*! \brief I2S modes. */ +typedef enum +{ + PAL_I2S_MODE_MASTER, /*!< Master mode. */ + PAL_I2S_MODE_SLAVE /*!< Slave mode. */ +} PalI2sMode_t; + +/*! \brief Channels. */ +typedef enum +{ + PAL_I2S_CH_LEFT_BIT = (1 << 0), /*!< Left channel bit. */ + PAL_I2S_CH_RIGHT_BIT = (1 << 1) /*!< Right channel bit. */ +} PalI2sChanMask_t; + +/*! \brief I2S configuration. */ +typedef struct +{ + PalI2sMode_t mode:8; /*!< Mode of operation. */ + uint32_t rate; /*!< Sample rate. */ + uint8_t bitDepth; /*!< Sample bit depth. */ + uint8_t chan; /*!< Enabled channels. */ + PalI2sCompCback_t frmCback; /*!< Get next read buffer callback. */ + void *pCtx; /*!< Opaque operation context. */ +} PalI2sConfig_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void PalI2sInit(void); +void PalI2sDeInit(void); + +/* Control and Status */ +PalI2sState_t PalI2sGetState(void); +void PalI2sConfig(PalI2sConfig_t *pCfg); +void PalI2sDeConfig(void); + +/* Data Transfer */ +void PalI2sReadData(uint8_t *pData, uint16_t len); +void PalI2sWriteData(const uint8_t *pData, uint16_t len); + +/*! \} */ /* PAL_I2S */ + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_I2S_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_io_exp.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_io_exp.h index 14cac155141..012f97a42ed 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_io_exp.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_io_exp.h @@ -1,29 +1,29 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief I/O expander driver definition. + * \file + * + * \brief I/O expander driver definition. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_IO_EXP_H #define PAL_IO_EXP_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_led.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_led.h index f6e31129e68..5f81d16efda 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_led.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_led.h @@ -1,29 +1,29 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief LED driver definition. + * \file + * + * \brief LED driver definition. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_LED_H #define PAL_LED_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -37,12 +37,12 @@ extern "C" { **************************************************************************************************/ /*! \brief Reserved LED IDs. */ -typedef enum +enum { - /* Common debug signals. */ - PAL_LED_ID_CPU_ACTIVE = 0x18, /*!< CPU active LED ID. */ - PAL_LED_ID_ERROR = 0x19, /*!< Error LED ID. */ -} PalLedId_t; + /* System signals. */ + PAL_LED_ID_CPU_ACTIVE = 0x30, /*!< CPU active LED ID. */ + PAL_LED_ID_ERROR = 0x31, /*!< Error LED ID. */ +}; /************************************************************************************************** Function Declarations @@ -55,8 +55,6 @@ void PalLedDeInit(void); /* Control and Status */ void PalLedOn(uint8_t id); void PalLedOff(uint8_t id); -void PalLedOnGroup(uint32_t mask); -void PalLedOffGroup(uint32_t mask); /*! \} */ /* PAL_LED */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_nvm.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_nvm.h deleted file mode 100644 index 0de49fc9246..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_nvm.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Pal NVM driver. - */ -/*************************************************************************************************/ - -#ifndef PAL_NVM_H -#define PAL_NVM_H - -#include "stack/platform/include/pal_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \addtogroup PAL_NVM - * \{ */ - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/*! NVM sector size. */ -#define PAL_NVM_SECTOR_SIZE 0x1000 - -/*! NVM word size. */ -#define PAL_NVM_WORD_SIZE 4 - -/************************************************************************************************** - Data Types -**************************************************************************************************/ - -/*! \brief Callback. This may be returned in interrupt context. */ -typedef void (*PalNvmCback_t)(bool_t status); - -/*! \brief Operational states. */ -typedef enum -{ - PAL_NVM_STATE_UNINIT = 0, /*!< Uninitialized state. */ - PAL_NVM_STATE_ERROR = 0, /*!< Error state. */ - PAL_NVM_STATE_READY, /*!< Ready state. */ - PAL_NVM_STATE_BUSY /*!< Busy state. */ -} PalNvmState_t; - -/************************************************************************************************** - Function Declarations -**************************************************************************************************/ - -/* Initialization */ -void PalNvmInit(PalNvmCback_t actCback); -void PalNvmDeInit(void); - -/* Control and Status */ -PalNvmState_t PalNvmGetState(void); - -/* Data Transfer */ -void PalNvmRead(void *pBuf, uint32_t size, uint32_t srcAddr); -void PalNvmWrite(void *pBuf, uint32_t size, uint32_t dstAddr); -void PalNvmEraseSector(uint32_t size, uint32_t startAddr); - -/*! \} */ /* PAL_NVM */ - -#ifdef __cplusplus -}; -#endif - -#endif /* PAL_NVM_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio.h index efe84d3b5a7..bfea3badb3c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Radio interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Radio interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_RADIO_H #define PAL_RADIO_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -39,8 +41,6 @@ extern "C" { /*************************************************************************************************/ /*! * \brief Initialize RF path compensation. - * - * \return None. */ /*************************************************************************************************/ void PalRadioInitPathComp(void); @@ -60,6 +60,33 @@ void PalRadioInitPathComp(void); /*************************************************************************************************/ int8_t PalRadioGetActualTxPower(int8_t txPwr, bool_t compFlag); +/*************************************************************************************************/ +/*! + * \brief Request an increase in power. + * + * \param reqPwr Requested Power. + * \param delta Delta + * + * \return TxPower to be set + * + * If increasing power: the controller will increase one step if possible. + * If decreasing power: the controller will only decrease to the ceiling step. + */ +/*************************************************************************************************/ +int8_t PalRadioIncreasePower(int8_t reqPwr, int8_t delta); + +/*************************************************************************************************/ +/*! + * \brief Get the next acceptable power reduction step. + * + * \param txPwr Tx Power(expressed in 1dBm units). + * + * \return Lowest acceptable power reduction size. + * + */ +/*************************************************************************************************/ +int8_t PalRadioGetAcceptablePowerReduction(int8_t txPwr); + /*************************************************************************************************/ /*! * \brief Set RF path compensation. @@ -78,8 +105,6 @@ bool_t PalRadioWriteRfPathComp(int16_t txPathComp, int16_t rxPathComp); * * \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units). * \param pMaxTxPwr Return buffer for maximum transmit power (expressed in 1dBm units). - * - * \return None. */ /*************************************************************************************************/ void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr); @@ -90,8 +115,6 @@ void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr); * * \param pTxPathComp Return buffer for RF transmit path compensation value (expressed in 0.1dBm units). * \param pRxPathComp Return buffer for RF receive path compensation value (expressed in 0.1dBm units). - * - * \return None. */ /*************************************************************************************************/ void PalRadioReadRfPathComp(int16_t *pTxPathComp, int16_t *pRxPathComp); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio2.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio2.h new file mode 100644 index 00000000000..f7f9cbad19b --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_radio2.h @@ -0,0 +1,115 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Radio interface file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_RADIO_H +#define PAL_RADIO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup PAL_RADIO + * \{ */ + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/* Use this to enable debugging stuff */ +#define PAL_RADIO_DEBUG + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +typedef enum +{ + PAL_RADIO_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_RADIO_STATE_ERROR = 0, /*!< Error state. */ + PAL_RADIO_STATE_IDLE, /*!< Idle state. */ + PAL_RADIO_STATE_TX, /*!< Tx state. */ + PAL_RADIO_STATE_RX, /*!< Rx state. */ + PAL_RADIO_STATE_DIAG /*!< Diagnostics state. */ +} PalRadioState_t; + +typedef enum +{ + PAL_RADIO_STATUS_SUCCESS, /*!< Operation completed successfully. */ + PAL_RADIO_STATUS_FAILED, /*!< General failure. */ + PAL_RADIO_STATUS_TIMEOUT, /*!< Rx timed out. */ + PAL_RADIO_STATUS_CRC_FAILED /*!< Rx CRC match failed. */ +} PalRadioStatus_t; + +typedef enum +{ + PAL_RADIO_PHY_1M, /*!< 1M PHY. */ + PAL_RADIO_PHY_2M, /*!< 2M PHY. */ + PAL_RADIO_PHY_CODED_DEFAULT, /*!< Coded with options not specified. */ + PAL_RADIO_PHY_CODED_S2, /*!< Coded S2 PHY (500-kbps). */ + PAL_RADIO_PHY_CODED_S8 /*!< Coded S8 PHY (128-kbps). */ +} PalRadioPhy_t; + +/*! \brief Tx completion call signature. */ +typedef void (*PalRadioTxComp_t)(PalRadioStatus_t status); + +/*! \brief Rx completion call signature. */ +typedef void (*PalRadioRxComp_t)(PalRadioStatus_t status, uint32_t tstamp, PalRadioPhy_t phy, int8_t rssi); + +/************************************************************************************************** + Functions +**************************************************************************************************/ + +/* Initialization */ +void PalRadioInit(void); +void PalRadioDeInit(void); + +/* Control and Status */ +void PalRadioRegisterTxComplete(PalRadioTxComp_t cback); +void PalRadioRegisterRxComplete(PalRadioRxComp_t cback); +void PalRadioSetAccessAddress(uint32_t addr); +void PalRadioSetCrcInit(uint32_t crcInit); +void PalRadioSetChannel(uint8_t chIdx); +void PalRadioSetTxPower(int8_t level); +int8_t PalRadioGetTxPower(void); +void PalRadioSetPhy(PalRadioPhy_t txPhy, PalRadioPhy_t rxPhy); +void PalRadioSetDataWhitening(uint8_t ena); +void PalRadioSetPrbs15(uint8_t ena); +PalRadioState_t PalRadioGetState(void); + +/* Data Transfer */ +void PalRadioTxStart(uint32_t dueTime); +void PalRadioTxNext(uint32_t offsUsec); +void PalRadioTxData(uint8_t *pBuf, uint16_t len); +void PalRadioRxStart(uint32_t dueTime, uint32_t rxTimeoutUsec); +void PalRadioRxNext(uint32_t offsUsec, uint32_t rxTimeoutUsec); +void PalRadioRxData(uint8_t *pBuf, uint16_t len); +void PalRadioStop(void); + +/*! \} */ /* PAL_RADIO */ + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_RADIO_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_rtc.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_rtc.h index dd3ae97769a..4e45c4028e8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_rtc.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_rtc.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief RTC timer interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief RTC timer interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_RTC_H #define PAL_RTC_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -42,6 +44,24 @@ extern "C" { /*! \brief Clock frequency of the RTC timer used. */ #define PAL_RTC_TICKS_PER_SEC (32768) /* RTC ticks per second (with prescaler) */ +/*! \brief 23 RTC ticks time(700us) for xtal start up befor scheduler load. */ +#define PAL_HFCLK_OSC_SETTLE_TICKS (23) + +/*! \brief Platform RTC callback. */ +typedef void (*palRtcIrqCback_t)(void); + +/************************************************************************************************** + Type Definitions +**************************************************************************************************/ + +/*! \brief Operational states. */ +typedef enum +{ + PAL_RTC_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_RTC_STATE_ERROR = 0, /*!< Error state. */ + PAL_RTC_STATE_READY = 1 /*!< Ready state. */ +} PalRtcState_t; + /************************************************************************************************** Function Declarations **************************************************************************************************/ @@ -50,11 +70,10 @@ extern "C" { void PalRtcInit(void); /* Control and Status */ -void PalRtcEnableCompareIrq(void); -void PalRtcDisableCompareIrq(void); +void PalRtcEnableCompareIrq(uint8_t channelId); +void PalRtcDisableCompareIrq(uint8_t channelId); uint32_t PalRtcCounterGet(void); -void PalRtcCompareSet(uint32_t value); -uint32_t PalRtcCompareGet(void); +void PalRtcCompareSet(uint8_t channelId, uint32_t value); /*! \} */ /* PAL_RTC */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_spi.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_spi.h new file mode 100644 index 00000000000..78f7e94ef76 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_spi.h @@ -0,0 +1,86 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief SPI driver definition. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef PAL_SPI_H +#define PAL_SPI_H + +#include "pal_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup PAL_SPI + * \{ */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Signaling mode. */ +typedef enum +{ + PAL_SPI_MODE_SLAVE, /*!< Slave mode. */ + PAL_SPI_MODE_MASTER /*!< Master mode. */ +} PalSpiMode_t; + +/*! \brief Data exchange completion callback. */ +typedef void (*PalSpiCompCback)(void); + +/*! \brief Peripheral configuration. */ +typedef struct +{ + uint32_t clkRateHz; /*!< Clock rate in Hz. */ + PalSpiMode_t mode; /*!< Signaling mode. */ + PalSpiCompCback compCback; /*!< Data exchange completion callback. */ +} PalSpiConfig_t; + +/*! \brief Operational states. */ +typedef enum +{ + PAL_SPI_STATE_UNINIT = 0, /*!< Uninitialized state. */ + PAL_SPI_STATE_ERROR = 0, /*!< Error state. */ + PAL_SPI_STATE_READY, /*!< Ready state. */ + PAL_SPI_STATE_BUSY /*!< Data exchange in progress. */ +} PalSpiState_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void PalSpiInit(const PalSpiConfig_t *pCfg); +void PalSpiDeInit(void); + +/* Control and Status */ +PalSpiState_t PalSpiGetState(void); + +/* Data Transfer */ +void PalSpiDataExchange(uint8_t *pRdData, uint16_t rdDataLen, const uint8_t *pWrData, uint16_t wrDataLen); + +/*! \} */ /* PAL_SPI */ + +#ifdef __cplusplus +}; +#endif + +#endif /* PAL_SPI_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_sys.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_sys.h index 18272cf2328..fb7928b8be3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_sys.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_sys.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief System hooks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief System hooks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_SYS_H #define PAL_SYS_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -32,18 +34,46 @@ extern "C" { /*! \addtogroup PAL_SYS * \{ */ +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/* Common error handling routines; for use with PAL implementation only. */ + +#ifdef DEBUG + +/*! \brief Parameter check. */ +#define PAL_SYS_ASSERT(expr) { if (!(expr)) { PalSysAssertTrap(); } } + +#else + +/*! \brief Parameter check (disabled). */ +#define PAL_SYS_ASSERT(expr) + +#endif + /************************************************************************************************** Function Declarations **************************************************************************************************/ + +/* Initialization */ +void PalSysInit(void); + +/* Diagnostics */ void PalSysAssertTrap(void); void PalSysSetTrap(bool_t enable); uint32_t PalSysGetAssertCount(void); uint32_t PalSysGetStackUsage(void); + +/* Power Management */ void PalSysSleep(void); bool_t PalSysIsBusy(void); void PalSysSetBusy(void); void PalSysSetIdle(void); -void PalSysInit(void); + +/* Critical Section */ +void PalEnterCs(void); +void PalExitCs(void); /*! \} */ /* PAL_SYS */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_timer.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_timer.h index 4b249f4a922..282722dc0d3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_timer.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_timer.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Timer interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Timer interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_TIMER_H #define PAL_TIMER_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -36,12 +38,6 @@ extern "C" { Macros **************************************************************************************************/ -/*! \brief Timer micro seconds to ticks. */ -#define PAL_TIMER_US_TO_TICKS(us) (us) - -/*! \brief Timer ticks to micro seconds. */ -#define PAL_TIMER_TICKS_TO_US(ticks) (ticks) - /*! \brief Operational states. */ typedef enum { @@ -68,9 +64,9 @@ void PalTimerDeInit(void); /* Control and Status */ PalTimerState_t PalTimerGetState(void); -uint32_t PalTimerGetCurrentTime(void); -void PalTimerStart(uint32_t startTime); +void PalTimerStart(uint32_t expUsec); void PalTimerStop(void); +uint32_t PalTimerGetCurrentTime(void); /*! \} */ /* PAL_TIMER */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_twi.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_twi.h index 6a3761e6cc4..2fd3ed312d8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_twi.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_twi.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief TWI driver definition. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief TWI driver definition. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_TWI_H #define PAL_TWI_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -64,7 +66,8 @@ typedef enum PAL_TWI_STATE_UNINIT = 0, /*!< Uninitialized state. */ PAL_TWI_STATE_ERROR = 0, /*!< Error state. */ PAL_TWI_STATE_READY, /*!< Ready state. */ - PAL_TWI_STATE_BUSY /*!< Busy (data transfer) state. */ + PAL_TWI_STATE_BUSY_DATA_PEND, /*!< Busy state (operation in progress), Data pending substate. */ + PAL_TWI_STATE_BUSY_DATA_XFER /*!< Busy state (operation in progress), Data transfer substate. */ } PalTwiState_t; /************************************************************************************************** diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_types.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_types.h index a8e4dfe7f8a..7b876eaeb46 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_types.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_types.h @@ -1,30 +1,29 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file pal_types.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Platform-independent data types. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Platform-independent data types. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_TYPES_H #define PAL_TYPES_H -#include -#include - #ifdef __cplusplus extern "C" { #endif @@ -33,31 +32,34 @@ extern "C" { * \{ */ /************************************************************************************************** - Macros + Data Types **************************************************************************************************/ -#ifndef NULL -/*! \brief NULL reference */ -#define NULL 0 -#endif +/** \name Integer Data Types + * + */ +/**@{*/ -#ifndef TRUE -/*! \brief Boolean True */ -#define TRUE 1 +#include +#include + +#ifndef bool_t + #define bool_t uint8_t #endif #ifndef FALSE -/*! \brief Boolean False */ -#define FALSE 0 + #define FALSE 0 #endif -/*! \brief Boolean data type */ -typedef uint8_t bool_t; +#ifndef TRUE + #define TRUE (!FALSE) +#endif -/*! \} */ /* PAL_TYPES */ +/*! \} */ /* Integer Data Types */ #ifdef __cplusplus }; #endif +/*! \} */ /* PAL_TYPES */ #endif /* PAL_TYPES_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_uart.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_uart.h index 6d46927a70b..b3b8baec1fb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_uart.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/platform/include/pal_uart.h @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief UART driver definition. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief UART driver definition. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef PAL_UART_H #define PAL_UART_H -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" #ifdef __cplusplus extern "C" { @@ -42,9 +44,9 @@ typedef void (*PalUartCompCback_t)(void); /*! \brief Peripheral configuration. */ typedef struct { - uint32_t baud; /*!< Baud rate. */ PalUartCompCback_t rdCback; /*!< Read data completion callback. */ PalUartCompCback_t wrCback; /*!< Write data completion callback. */ + uint32_t baud; /*!< Baud rate. */ bool_t hwFlow; /*!< Use HW Flow control */ } PalUartConfig_t; @@ -60,9 +62,10 @@ typedef enum /*! \brief Reserved UART ID. */ typedef enum { - PAL_UART_ID_USER = 0x00, /*!< UART 0. */ - PAL_UART_ID_CHCI = 0xF0, /*!< UART CHCI. */ - PAL_UART_ID_TERMINAL = 0xF1, /*!< UART TERMINAL. */ + PAL_UART_ID_USER = 0, /*!< UART 0. */ + PAL_UART_ID_CHCI = 1, /*!< UART CHCI. */ + PAL_UART_ID_TERMINAL = 2, /*!< UART TERMINAL. */ + PAL_UART_ID_MAX /*!< Number of UART instances. */ } PalUartId_t; /************************************************************************************************** diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/hci_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/hci_defs.h index f9bf8d270cf..69eeffa0ebe 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/hci_defs.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/hci_defs.h @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file hci_defs.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI constants and definitions from the Bluetooth specification. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief HCI constants and definitions from the Bluetooth specification. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef HCI_DEFS_H @@ -33,114 +35,118 @@ extern "C" { * */ /**@{*/ -#define HCI_CMD_HDR_LEN 3 /*!< \brief Command packet header length */ -#define HCI_ACL_HDR_LEN 4 /*!< \brief ACL packet header length */ -#define HCI_ISO_HDR_LEN 4 /*!< \brief ISO packet header length */ -#define HCI_EVT_HDR_LEN 2 /*!< \brief Event packet header length */ -#define HCI_EVT_PARAM_MAX_LEN 255 /*!< \brief Maximum length of event packet parameters */ -#define HCI_ACL_DEFAULT_LEN 27 /*!< \brief Default maximum ACL packet length */ -#define HCI_PB_FLAG_MASK 0x3000 /*!< \brief ACL packet boundary flag mask */ -#define HCI_PB_START_H2C 0x0000 /*!< \brief Packet boundary flag, start, host-to-controller */ -#define HCI_PB_CONTINUE 0x1000 /*!< \brief Packet boundary flag, continue */ -#define HCI_PB_START_C2H 0x2000 /*!< \brief Packet boundary flag, start, controller-to-host */ -#define HCI_HANDLE_MASK 0x0FFF /*!< \brief Mask for handle bits in ACL packet */ -#define HCI_HANDLE_NONE 0xFFFF /*!< \brief Value for invalid handle */ +#define HCI_CMD_HDR_LEN 3 /*!< Command packet header length */ +#define HCI_ACL_HDR_LEN 4 /*!< ACL packet header length */ +#define HCI_ISO_HDR_LEN 4 /*!< ISO packet header length */ +#define HCI_EVT_HDR_LEN 2 /*!< Event packet header length */ +#define HCI_EVT_PARAM_MAX_LEN 255 /*!< Maximum length of event packet parameters */ +#define HCI_ACL_DEFAULT_LEN 27 /*!< Default maximum ACL packet length */ +#define HCI_PB_FLAG_MASK 0x3000 /*!< ACL packet boundary flag mask */ +#define HCI_PB_START_H2C 0x0000 /*!< Packet boundary flag, start, host-to-controller */ +#define HCI_PB_CONTINUE 0x1000 /*!< Packet boundary flag, continue */ +#define HCI_PB_START_C2H 0x2000 /*!< Packet boundary flag, start, controller-to-host */ +#define HCI_HANDLE_MASK 0x0FFF /*!< Mask for handle bits in ACL packet */ +#define HCI_HANDLE_NONE 0xFFFF /*!< Value for invalid handle */ + +#define HCI_ISO_DL_MIN_LEN 4 /*!< ISO Data Load header minimum length */ +#define HCI_ISO_DL_MAX_LEN 8 /*!< ISO Data Load header maximum length */ +#define HCI_ISO_TS_LEN 4 /*!< ISO Data Load timestamp length */ /**@}*/ /** \name Packet types * */ -#define HCI_CMD_TYPE 1 /*!< \brief HCI command packet */ -#define HCI_ACL_TYPE 2 /*!< \brief HCI ACL data packet */ -#define HCI_EVT_TYPE 4 /*!< \brief HCI event packet */ -#define HCI_ISO_TYPE 5 /*!< \brief HCI ISO data packet */ +#define HCI_CMD_TYPE 0x01 /*!< HCI command packet */ +#define HCI_ACL_TYPE 0x02 /*!< HCI ACL data packet */ +#define HCI_EVT_TYPE 0x04 /*!< HCI event packet */ +#define HCI_ISO_TYPE 0x05 /*!< HCI ISO data packet */ /**@}*/ /** \name Error codes * */ /**@{*/ -#define HCI_SUCCESS 0x00 /*!< \brief Success */ -#define HCI_ERR_UNKNOWN_CMD 0x01 /*!< \brief Unknown HCI command */ -#define HCI_ERR_UNKNOWN_HANDLE 0x02 /*!< \brief Unknown connection identifier */ -#define HCI_ERR_HARDWARE_FAILURE 0x03 /*!< \brief Hardware failure */ -#define HCI_ERR_PAGE_TIMEOUT 0x04 /*!< \brief Page timeout */ -#define HCI_ERR_AUTH_FAILURE 0x05 /*!< \brief Authentication failure */ -#define HCI_ERR_KEY_MISSING 0x06 /*!< \brief PIN or key missing */ -#define HCI_ERR_MEMORY_EXCEEDED 0x07 /*!< \brief Memory capacity exceeded */ -#define HCI_ERR_CONN_TIMEOUT 0x08 /*!< \brief Connection timeout */ -#define HCI_ERR_CONN_LIMIT 0x09 /*!< \brief Connection limit exceeded */ -#define HCI_ERR_SYNCH_CONN_LIMIT 0x0A /*!< \brief Synchronous connection limit exceeded */ -#define HCI_ERR_ACL_CONN_EXISTS 0x0B /*!< \brief ACL connection already exists */ -#define HCI_ERR_CMD_DISALLOWED 0x0C /*!< \brief Command disallowed */ -#define HCI_ERR_REJ_RESOURCES 0x0D /*!< \brief Connection rejected limited resources */ -#define HCI_ERR_REJ_SECURITY 0x0E /*!< \brief Connection rejected security reasons */ -#define HCI_ERR_REJ_BD_ADDR 0x0F /*!< \brief Connection rejected unacceptable BD_ADDR */ -#define HCI_ERR_ACCEPT_TIMEOUT 0x10 /*!< \brief Connection accept timeout exceeded */ -#define HCI_ERR_UNSUP_FEAT 0x11 /*!< \brief Unsupported feature or parameter value */ -#define HCI_ERR_INVALID_PARAM 0x12 /*!< \brief Invalid HCI command parameters */ -#define HCI_ERR_REMOTE_TERMINATED 0x13 /*!< \brief Remote user terminated connection */ -#define HCI_ERR_REMOTE_RESOURCES 0x14 /*!< \brief Remote device low resources */ -#define HCI_ERR_REMOTE_POWER_OFF 0x15 /*!< \brief Remote device power off */ -#define HCI_ERR_LOCAL_TERMINATED 0x16 /*!< \brief Connection terminated by local host */ -#define HCI_ERR_REPEATED_ATTEMPTS 0x17 /*!< \brief Repeated attempts */ -#define HCI_ERR_PAIRING_NOT_ALLOWED 0x18 /*!< \brief Pairing not allowed */ -#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 /*!< \brief Unknown LMP PDU */ -#define HCI_ERR_UNSUP_REMOTE_FEAT 0x1A /*!< \brief Unsupported remote feature */ -#define HCI_ERR_SCO_OFFSET 0x1B /*!< \brief SCO offset rejected */ -#define HCI_ERR_SCO_INTERVAL 0x1C /*!< \brief SCO interval rejected */ -#define HCI_ERR_SCO_MODE 0x1D /*!< \brief SCO air mode rejected */ -#define HCI_ERR_LMP_PARAM 0x1E /*!< \brief Invalid LMP parameters */ -#define HCI_ERR_UNSPECIFIED 0x1F /*!< \brief Unspecified error */ -#define HCI_ERR_UNSUP_LMP_PARAM 0x20 /*!< \brief Unsupported LMP parameter value */ -#define HCI_ERR_ROLE_CHANGE 0x21 /*!< \brief Role change not allowed */ -#define HCI_ERR_LL_RESP_TIMEOUT 0x22 /*!< \brief LL response timeout */ -#define HCI_ERR_LMP_COLLISION 0x23 /*!< \brief LMP error transaction collision */ -#define HCI_ERR_LMP_PDU 0x24 /*!< \brief LMP pdu not allowed */ -#define HCI_ERR_ENCRYPT_MODE 0x25 /*!< \brief Encryption mode not acceptable */ -#define HCI_ERR_LINK_KEY 0x26 /*!< \brief Link key can not be changed */ -#define HCI_ERR_UNSUP_QOS 0x27 /*!< \brief Requested qos not supported */ -#define HCI_ERR_INSTANT_PASSED 0x28 /*!< \brief Instant passed */ -#define HCI_ERR_UNSUP_UNIT_KEY 0x29 /*!< \brief Pairing with unit key not supported */ -#define HCI_ERR_TRANSACT_COLLISION 0x2A /*!< \brief Different transaction collision */ -#define HCI_ERR_CHANNEL_CLASS 0x2E /*!< \brief Channel classification not supported */ -#define HCI_ERR_MEMORY 0x2F /*!< \brief Insufficient security */ -#define HCI_ERR_PARAMETER_RANGE 0x30 /*!< \brief Parameter out of mandatory range */ -#define HCI_ERR_ROLE_SWITCH_PEND 0x32 /*!< \brief Role switch pending */ -#define HCI_ERR_RESERVED_SLOT 0x34 /*!< \brief Reserved slot violation */ -#define HCI_ERR_ROLE_SWITCH 0x35 /*!< \brief Role switch failed */ -#define HCI_ERR_INQ_TOO_LARGE 0x36 /*!< \brief Extended inquiry response too large */ -#define HCI_ERR_UNSUP_SSP 0x37 /*!< \brief Secure simple pairing not supported by host */ -#define HCI_ERR_HOST_BUSY_PAIRING 0x38 /*!< \brief Host busy - pairing */ -#define HCI_ERR_NO_CHANNEL 0x39 /*!< \brief Connection rejected no suitable channel */ -#define HCI_ERR_CONTROLLER_BUSY 0x3A /*!< \brief Controller busy */ -#define HCI_ERR_CONN_INTERVAL 0x3B /*!< \brief Unacceptable connection interval */ -#define HCI_ERR_ADV_TIMEOUT 0x3C /*!< \brief Advertising timeout */ -#define HCI_ERR_MIC_FAILURE 0x3D /*!< \brief Connection terminated due to MIC failure */ -#define HCI_ERR_CONN_FAIL 0x3E /*!< \brief Connection failed to be established */ -#define HCI_ERR_MAC_CONN_FAIL 0x3F /*!< \brief MAC connection failed */ -#define HCI_ERR_COARSE_CLK_ADJ_REJ 0x40 /*!< \brief Coarse clock adjustment rejected */ -#define HCI_ERR_TYPE0_SUBMAP_NOT_DEF 0x41 /*!< \brief Type0 submap not defined */ -#define HCI_ERR_UNKNOWN_ADV_ID 0x42 /*!< \brief Unknown advertising identifier */ -#define HCI_ERR_LIMIT_REACHED 0x43 /*!< \brief Limit reached */ -#define HCI_ERR_OP_CANCELLED_BY_HOST 0x44 /*!< \brief Operation cancelled by host */ -/*! \brief New in version 5.1 */ -#define HCI_ERR_PKT_TOO_LONG 0x45 /*!< \brief Packet too long */ +#define HCI_SUCCESS 0x00 /*!< Success */ +#define HCI_ERR_UNKNOWN_CMD 0x01 /*!< Unknown HCI command */ +#define HCI_ERR_UNKNOWN_HANDLE 0x02 /*!< Unknown connection identifier */ +#define HCI_ERR_HARDWARE_FAILURE 0x03 /*!< Hardware failure */ +#define HCI_ERR_PAGE_TIMEOUT 0x04 /*!< Page timeout */ +#define HCI_ERR_AUTH_FAILURE 0x05 /*!< Authentication failure */ +#define HCI_ERR_KEY_MISSING 0x06 /*!< PIN or key missing */ +#define HCI_ERR_MEMORY_EXCEEDED 0x07 /*!< Memory capacity exceeded */ +#define HCI_ERR_CONN_TIMEOUT 0x08 /*!< Connection timeout */ +#define HCI_ERR_CONN_LIMIT 0x09 /*!< Connection limit exceeded */ +#define HCI_ERR_SYNCH_CONN_LIMIT 0x0A /*!< Synchronous connection limit exceeded */ +#define HCI_ERR_ACL_CONN_EXISTS 0x0B /*!< ACL connection already exists */ +#define HCI_ERR_CMD_DISALLOWED 0x0C /*!< Command disallowed */ +#define HCI_ERR_REJ_RESOURCES 0x0D /*!< Connection rejected limited resources */ +#define HCI_ERR_REJ_SECURITY 0x0E /*!< Connection rejected security reasons */ +#define HCI_ERR_REJ_BD_ADDR 0x0F /*!< Connection rejected unacceptable BD_ADDR */ +#define HCI_ERR_ACCEPT_TIMEOUT 0x10 /*!< Connection accept timeout exceeded */ +#define HCI_ERR_UNSUP_FEAT 0x11 /*!< Unsupported feature or parameter value */ +#define HCI_ERR_INVALID_PARAM 0x12 /*!< Invalid HCI command parameters */ +#define HCI_ERR_REMOTE_TERMINATED 0x13 /*!< Remote user terminated connection */ +#define HCI_ERR_REMOTE_RESOURCES 0x14 /*!< Remote device low resources */ +#define HCI_ERR_REMOTE_POWER_OFF 0x15 /*!< Remote device power off */ +#define HCI_ERR_LOCAL_TERMINATED 0x16 /*!< Connection terminated by local host */ +#define HCI_ERR_REPEATED_ATTEMPTS 0x17 /*!< Repeated attempts */ +#define HCI_ERR_PAIRING_NOT_ALLOWED 0x18 /*!< Pairing not allowed */ +#define HCI_ERR_UNKNOWN_LMP_PDU 0x19 /*!< Unknown LMP PDU */ +#define HCI_ERR_UNSUP_REMOTE_FEAT 0x1A /*!< Unsupported remote feature */ +#define HCI_ERR_SCO_OFFSET 0x1B /*!< SCO offset rejected */ +#define HCI_ERR_SCO_INTERVAL 0x1C /*!< SCO interval rejected */ +#define HCI_ERR_SCO_MODE 0x1D /*!< SCO air mode rejected */ +#define HCI_ERR_LMP_PARAM 0x1E /*!< Invalid LMP parameters */ +#define HCI_ERR_UNSPECIFIED 0x1F /*!< Unspecified error */ +#define HCI_ERR_UNSUP_LMP_PARAM 0x20 /*!< Unsupported LMP parameter value */ +#define HCI_ERR_ROLE_CHANGE 0x21 /*!< Role change not allowed */ +#define HCI_ERR_LL_RESP_TIMEOUT 0x22 /*!< LL response timeout */ +#define HCI_ERR_LMP_COLLISION 0x23 /*!< LMP error transaction collision */ +#define HCI_ERR_LMP_PDU 0x24 /*!< LMP pdu not allowed */ +#define HCI_ERR_ENCRYPT_MODE 0x25 /*!< Encryption mode not acceptable */ +#define HCI_ERR_LINK_KEY 0x26 /*!< Link key can not be changed */ +#define HCI_ERR_UNSUP_QOS 0x27 /*!< Requested qos not supported */ +#define HCI_ERR_INSTANT_PASSED 0x28 /*!< Instant passed */ +#define HCI_ERR_UNSUP_UNIT_KEY 0x29 /*!< Pairing with unit key not supported */ +#define HCI_ERR_TRANSACT_COLLISION 0x2A /*!< Different transaction collision */ +#define HCI_ERR_CHANNEL_CLASS 0x2E /*!< Channel classification not supported */ +#define HCI_ERR_MEMORY 0x2F /*!< Insufficient security */ +#define HCI_ERR_PARAMETER_RANGE 0x30 /*!< Parameter out of mandatory range */ +#define HCI_ERR_ROLE_SWITCH_PEND 0x32 /*!< Role switch pending */ +#define HCI_ERR_RESERVED_SLOT 0x34 /*!< Reserved slot violation */ +#define HCI_ERR_ROLE_SWITCH 0x35 /*!< Role switch failed */ +#define HCI_ERR_INQ_TOO_LARGE 0x36 /*!< Extended inquiry response too large */ +#define HCI_ERR_UNSUP_SSP 0x37 /*!< Secure simple pairing not supported by host */ +#define HCI_ERR_HOST_BUSY_PAIRING 0x38 /*!< Host busy - pairing */ +#define HCI_ERR_NO_CHANNEL 0x39 /*!< Connection rejected no suitable channel */ +#define HCI_ERR_CONTROLLER_BUSY 0x3A /*!< Controller busy */ +#define HCI_ERR_CONN_INTERVAL 0x3B /*!< Unacceptable connection interval */ +#define HCI_ERR_ADV_TIMEOUT 0x3C /*!< Advertising timeout */ +#define HCI_ERR_MIC_FAILURE 0x3D /*!< Connection terminated due to MIC failure */ +#define HCI_ERR_CONN_FAIL 0x3E /*!< Connection failed to be established */ +#define HCI_ERR_MAC_CONN_FAIL 0x3F /*!< MAC connection failed */ +#define HCI_ERR_COARSE_CLK_ADJ_REJ 0x40 /*!< Coarse clock adjustment rejected */ +#define HCI_ERR_TYPE0_SUBMAP_NOT_DEF 0x41 /*!< Type0 submap not defined */ +#define HCI_ERR_UNKNOWN_ADV_ID 0x42 /*!< Unknown advertising identifier */ +#define HCI_ERR_LIMIT_REACHED 0x43 /*!< Limit reached */ +#define HCI_ERR_OP_CANCELLED_BY_HOST 0x44 /*!< Operation cancelled by host */ +/* Version 5.1 */ +#define HCI_ERR_PKT_TOO_LONG 0x45 /*!< Packet too long */ /**@}*/ /** \name Command groups * */ /**@{*/ -#define HCI_OGF_NOP 0x00 /*!< \brief No operation */ -#define HCI_OGF_LINK_CONTROL 0x01 /*!< \brief Link control */ -#define HCI_OGF_LINK_POLICY 0x02 /*!< \brief Link policy */ -#define HCI_OGF_CONTROLLER 0x03 /*!< \brief Controller and baseband */ -#define HCI_OGF_INFORMATIONAL 0x04 /*!< \brief Informational parameters */ -#define HCI_OGF_STATUS 0x05 /*!< \brief Status parameters */ -#define HCI_OGF_TESTING 0x06 /*!< \brief Testing */ -#define HCI_OGF_LE_CONTROLLER 0x08 /*!< \brief LE controller */ -#define HCI_OGF_VENDOR_SPEC 0x3F /*!< \brief Vendor specific */ +#define HCI_OGF_NOP 0x00 /*!< No operation */ +#define HCI_OGF_LINK_CONTROL 0x01 /*!< Link control */ +#define HCI_OGF_LINK_POLICY 0x02 /*!< Link policy */ +#define HCI_OGF_CONTROLLER 0x03 /*!< Controller and baseband */ +#define HCI_OGF_INFORMATIONAL 0x04 /*!< Informational parameters */ +#define HCI_OGF_STATUS 0x05 /*!< Status parameters */ +#define HCI_OGF_TESTING 0x06 /*!< Testing */ +#define HCI_OGF_LE_CONTROLLER 0x08 /*!< LE controller */ +#define HCI_OGF_VENDOR_SPEC 0x3F /*!< Vendor specific */ /**@}*/ /** \name NOP command @@ -158,7 +164,7 @@ extern "C" { #define HCI_OCF_READ_REMOTE_VER_INFO 0x1D /**@}*/ -/*! \brief Link policy commands (none used for LE) */ +/* Link policy commands (none used for LE) */ /** \name Controller and baseband commands * @@ -170,9 +176,13 @@ extern "C" { #define HCI_OCF_SET_CONTROLLER_TO_HOST_FC 0x31 #define HCI_OCF_HOST_BUFFER_SIZE 0x33 #define HCI_OCF_HOST_NUM_CMPL_PKTS 0x35 +/* Version 4.1 */ #define HCI_OCF_SET_EVENT_MASK_PAGE2 0x63 #define HCI_OCF_READ_AUTH_PAYLOAD_TO 0x7B #define HCI_OCF_WRITE_AUTH_PAYLOAD_TO 0x7C + +/* Version 5.2 */ +#define HCI_OCF_CONFIG_DATA_PATH 0x83 /**@}*/ /** \name Informational commands @@ -184,6 +194,11 @@ extern "C" { #define HCI_OCF_READ_LOCAL_SUP_FEAT 0x03 #define HCI_OCF_READ_BUF_SIZE 0x05 #define HCI_OCF_READ_BD_ADDR 0x09 + +/* Version 5.2 */ +#define HCI_OCF_READ_LOCAL_SUP_CODECS 0x0D +#define HCI_OCF_READ_LOCAL_SUP_CODEC_CAP 0x0E +#define HCI_OCF_READ_LOCAL_SUP_CONTROLLER_DLY 0x0F /**@}*/ /** \name Status commands @@ -227,10 +242,10 @@ extern "C" { #define HCI_OCF_LE_RECEIVER_TEST 0x1D #define HCI_OCF_LE_TRANSMITTER_TEST 0x1E #define HCI_OCF_LE_TEST_END 0x1F -/*! \brief New in version 4.1 */ +/* Version 4.1 */ #define HCI_OCF_LE_REM_CONN_PARAM_REP 0x20 #define HCI_OCF_LE_REM_CONN_PARAM_NEG_REP 0x21 -/*! \brief New in version 4.2 */ +/* Version 4.2 */ #define HCI_OCF_LE_SET_DATA_LEN 0x22 #define HCI_OCF_LE_READ_DEF_DATA_LEN 0x23 #define HCI_OCF_LE_WRITE_DEF_DATA_LEN 0x24 @@ -245,7 +260,7 @@ extern "C" { #define HCI_OCF_LE_SET_ADDR_RES_ENABLE 0x2D #define HCI_OCF_LE_SET_RES_PRIV_ADDR_TO 0x2E #define HCI_OCF_LE_READ_MAX_DATA_LEN 0x2F -/*! \brief New in version 5.0 */ +/* Version 5.0 */ #define HCI_OCF_LE_READ_PHY 0x30 #define HCI_OCF_LE_SET_DEF_PHY 0x31 #define HCI_OCF_LE_SET_PHY 0x32 @@ -277,7 +292,7 @@ extern "C" { #define HCI_OCF_LE_READ_RF_PATH_COMP 0x4C #define HCI_OCF_LE_WRITE_RF_PATH_COMP 0x4D #define HCI_OCF_LE_SET_PRIVACY_MODE 0x4E -/*! \brief New in version 5.1 */ +/* Version 5.1 */ #define HCI_OCF_LE_RECEIVER_TEST_V3 0x4F #define HCI_OCF_LE_TRANSMITTER_TEST_V3 0x50 #define HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS 0x51 @@ -295,8 +310,8 @@ extern "C" { #define HCI_OCF_LE_SET_DEFAULT_PAST_PARAM 0x5D #define HCI_OCF_LE_GENERATE_DHKEY_V2 0x5E #define HCI_OCF_LE_MODIFY_SLEEP_CLK_ACC 0x5F -/*! \brief New in version Milan */ -#define HCI_OCF_LE_READ_ISO_BUFFER_SIZE 0x60 +/* Version 5.2 */ +#define HCI_OCF_LE_READ_BUF_SIZE_V2 0x60 #define HCI_OCF_LE_READ_ISO_TX_SYNC 0x61 #define HCI_OCF_LE_SET_CIG_PARAMS 0x62 #define HCI_OCF_LE_SET_CIG_PARAMS_TEST 0x63 @@ -306,16 +321,23 @@ extern "C" { #define HCI_OCF_LE_REJECT_CIS_REQ 0x67 #define HCI_OCF_LE_CREATE_BIG 0x68 #define HCI_OCF_LE_CREATE_BIG_TEST 0x69 -#define HCI_OCF_LE_BIG_CREATE_SYNC 0x6A -#define HCI_OCF_LE_TERMINATE_BIG 0x6B +#define HCI_OCF_LE_TERMINATE_BIG 0x6A +#define HCI_OCF_LE_BIG_CREATE_SYNC 0x6B #define HCI_OCF_LE_BIG_TERMINATE_SYNC 0x6C #define HCI_OCF_LE_REQUEST_PEER_SCA 0x6D #define HCI_OCF_LE_SETUP_ISO_DATA_PATH 0x6E #define HCI_OCF_LE_REMOVE_ISO_DATA_PATH 0x6F #define HCI_OCF_LE_ISO_TX_TEST 0x70 #define HCI_OCF_LE_ISO_RX_TEST 0x71 -#define HCI_OCF_LE_ISO_READ_TEST_COUNTER 0x72 -#define HCI_OCF_LE_ISO_TERMINATE_TEST 0x73 +#define HCI_OCF_LE_ISO_READ_TEST_COUNTERS 0x72 +#define HCI_OCF_LE_ISO_TEST_END 0x73 +#define HCI_OCF_LE_SET_HOST_FEATURE 0x74 +#define HCI_OCF_LE_READ_ISO_LINK_QUAL 0x75 +#define HCI_OCF_LE_READ_ENHANCED_TX_POWER 0x76 +#define HCI_OCF_LE_READ_REMOTE_TX_POWER 0x77 +#define HCI_OCF_LE_SET_PATH_LOSS_REPORTING_PARAMS 0x78 +#define HCI_OCF_LE_SET_PATH_LOSS_REPORTING_ENABLE 0x79 +#define HCI_OCF_LE_SET_TX_POWER_REPORT_ENABLE 0x7A /**@}*/ /** \name Opcode manipulation macros @@ -342,12 +364,16 @@ extern "C" { #define HCI_OPCODE_SET_EVENT_MASK_PAGE2 HCI_OPCODE(HCI_OGF_CONTROLLER, HCI_OCF_SET_EVENT_MASK_PAGE2) #define HCI_OPCODE_READ_AUTH_PAYLOAD_TO HCI_OPCODE(HCI_OGF_CONTROLLER, HCI_OCF_READ_AUTH_PAYLOAD_TO) #define HCI_OPCODE_WRITE_AUTH_PAYLOAD_TO HCI_OPCODE(HCI_OGF_CONTROLLER, HCI_OCF_WRITE_AUTH_PAYLOAD_TO) +#define HCI_OPCODE_CONFIG_DATA_PATH HCI_OPCODE(HCI_OGF_CONTROLLER, HCI_OCF_CONFIG_DATA_PATH) #define HCI_OPCODE_READ_LOCAL_VER_INFO HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_VER_INFO) #define HCI_OPCODE_READ_LOCAL_SUP_CMDS HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_SUP_CMDS) #define HCI_OPCODE_READ_LOCAL_SUP_FEAT HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_SUP_FEAT) #define HCI_OPCODE_READ_BUF_SIZE HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_BUF_SIZE) #define HCI_OPCODE_READ_BD_ADDR HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_BD_ADDR) +#define HCI_OPCODE_READ_LOCAL_SUP_CODECS HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_SUP_CODECS) +#define HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_SUP_CODEC_CAP) +#define HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY HCI_OPCODE(HCI_OGF_INFORMATIONAL, HCI_OCF_READ_LOCAL_SUP_CONTROLLER_DLY) #define HCI_OPCODE_READ_RSSI HCI_OPCODE(HCI_OGF_STATUS, HCI_OCF_READ_RSSI) @@ -381,10 +407,10 @@ extern "C" { #define HCI_OPCODE_LE_RECEIVER_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_RECEIVER_TEST) #define HCI_OPCODE_LE_TRANSMITTER_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_TRANSMITTER_TEST) #define HCI_OPCODE_LE_TEST_END HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_TEST_END) -/*! \brief New in version 4.1 */ +/* Version 4.1 */ #define HCI_OPCODE_LE_REM_CONN_PARAM_REP HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_REM_CONN_PARAM_REP) #define HCI_OPCODE_LE_REM_CONN_PARAM_NEG_REP HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_REM_CONN_PARAM_NEG_REP) -/*! \brief New in version 4.2 */ +/* Version 4.2 */ #define HCI_OPCODE_LE_SET_DATA_LEN HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_DATA_LEN) #define HCI_OPCODE_LE_READ_DEF_DATA_LEN HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_DEF_DATA_LEN) #define HCI_OPCODE_LE_WRITE_DEF_DATA_LEN HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_WRITE_DEF_DATA_LEN) @@ -399,7 +425,7 @@ extern "C" { #define HCI_OPCODE_LE_SET_ADDR_RES_ENABLE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_ADDR_RES_ENABLE) #define HCI_OPCODE_LE_SET_RES_PRIV_ADDR_TO HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_RES_PRIV_ADDR_TO) #define HCI_OPCODE_LE_READ_MAX_DATA_LEN HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_MAX_DATA_LEN) -/*! \brief New in version 5.0 */ +/* Version 5.0 */ #define HCI_OPCODE_LE_READ_PHY HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_PHY) #define HCI_OPCODE_LE_SET_DEF_PHY HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_DEF_PHY) #define HCI_OPCODE_LE_SET_PHY HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_PHY) @@ -431,7 +457,7 @@ extern "C" { #define HCI_OPCODE_LE_WRITE_RF_PATH_COMP HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_WRITE_RF_PATH_COMP) #define HCI_OPCODE_LE_READ_RF_PATH_COMP HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_RF_PATH_COMP) #define HCI_OPCODE_LE_SET_PRIVACY_MODE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_PRIVACY_MODE) -/*! \brief New in version 5.1 */ +/* Version 5.1 */ #define HCI_OPCODE_LE_RECEIVER_TEST_V3 HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_RECEIVER_TEST_V3) #define HCI_OPCODE_LE_TRANSMITTER_TEST_V3 HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_TRANSMITTER_TEST_V3) #define HCI_OPCODE_LE_SET_CONNLESS_CTE_TX_PARAMS HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_CONNLESS_CTE_TX_PARAMS) @@ -449,8 +475,8 @@ extern "C" { #define HCI_OPCODE_LE_SET_DEFAULT_PAST_PARAM HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_DEFAULT_PAST_PARAM) #define HCI_OPCODE_LE_GENERATE_DHKEY_V2 HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_GENERATE_DHKEY_V2) #define HCI_OPCODE_LE_MODIFY_SLEEP_CLK_ACC HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_MODIFY_SLEEP_CLK_ACC) -/*! \brief New in version Milan */ -#define HCI_OPCODE_LE_READ_ISO_BUFFER_SIZE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_ISO_BUFFER_SIZE) +/* Version 5.2 */ +#define HCI_OPCODE_LE_READ_BUF_SIZE_V2 HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_BUF_SIZE_V2) #define HCI_OPCODE_LE_READ_ISO_TX_SYNC HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_ISO_TX_SYNC) #define HCI_OPCODE_LE_SET_CIG_PARAMS HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_CIG_PARAMS) #define HCI_OPCODE_LE_SET_CIG_PARAMS_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_CIG_PARAMS_TEST) @@ -460,19 +486,26 @@ extern "C" { #define HCI_OPCODE_LE_REJECT_CIS_REQ HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_REJECT_CIS_REQ) #define HCI_OPCODE_LE_CREATE_BIG HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_CREATE_BIG) #define HCI_OPCODE_LE_CREATE_BIG_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_CREATE_BIG_TEST) -#define HCI_OPCODE_LE_BIG_CREATE_SYNC HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_BIG_CREATE_SYNC) #define HCI_OPCODE_LE_TERMINATE_BIG HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_TERMINATE_BIG) +#define HCI_OPCODE_LE_BIG_CREATE_SYNC HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_BIG_CREATE_SYNC) #define HCI_OPCODE_LE_BIG_TERMINATE_SYNC HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_BIG_TERMINATE_SYNC) #define HCI_OPCODE_LE_REQUEST_PEER_SCA HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_REQUEST_PEER_SCA) #define HCI_OPCODE_LE_SETUP_ISO_DATA_PATH HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SETUP_ISO_DATA_PATH) #define HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_REMOVE_ISO_DATA_PATH) #define HCI_OPCODE_LE_ISO_TX_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_TX_TEST) #define HCI_OPCODE_LE_ISO_RX_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_RX_TEST) -#define HCI_OPCODE_LE_ISO_READ_TEST_COUNTER HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_READ_TEST_COUNTER) -#define HCI_OPCODE_LE_ISO_TERMINATE_TEST HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_TERMINATE_TEST) +#define HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_READ_TEST_COUNTERS) +#define HCI_OPCODE_LE_ISO_TEST_END HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_ISO_TEST_END) +#define HCI_OPCODE_LE_SET_HOST_FEATURE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_HOST_FEATURE) +#define HCI_OPCODE_LE_READ_ISO_LINK_QUAL HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_ISO_LINK_QUAL) +#define HCI_OPCODE_LE_READ_ENHANCED_TX_POWER HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_ENHANCED_TX_POWER) +#define HCI_OPCODE_LE_READ_REMOTE_TX_POWER HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_READ_REMOTE_TX_POWER) +#define HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_PARAMS HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_PATH_LOSS_REPORTING_PARAMS) +#define HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_ENABLE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_PATH_LOSS_REPORTING_ENABLE) +#define HCI_OPCODE_LE_SET_TX_POWER_REPORT_ENABLE HCI_OPCODE(HCI_OGF_LE_CONTROLLER, HCI_OCF_LE_SET_TX_POWER_REPORT_ENABLE) /**@}*/ -/** \name ARM Vendor Specific +/** \name Packetcraft Vendor Specific * */ /**@{*/ @@ -495,12 +528,16 @@ extern "C" { #define HCI_LEN_SET_CONTROLLER_TO_HOST_FC 1 #define HCI_LEN_HOST_BUFFER_SIZE 8 #define HCI_LEN_HOST_NUM_CMPL_PKTS 1 +#define HCI_LEN_CONFIG_DATA_PATH(cLen) (3 + (cLen)) #define HCI_LEN_READ_LOCAL_VER_INFO 0 #define HCI_LEN_READ_LOCAL_SUP_CMDS 0 #define HCI_LEN_READ_LOCAL_SUP_FEAT 0 #define HCI_LEN_READ_BUF_SIZE 0 #define HCI_LEN_READ_BD_ADDR 0 +#define HCI_LEN_READ_LOCAL_SUP_CODECS 0 +#define HCI_LEN_READ_LOCAL_SUP_CODEC_CAP 7 +#define HCI_LEN_READ_LOCAL_SUP_CONTROLLER_DLY(ccLen) (8 + (ccLen)) #define HCI_LEN_READ_RSSI 2 #define HCI_LEN_READ_AUTH_PAYLOAD_TO 2 @@ -536,10 +573,10 @@ extern "C" { #define HCI_LEN_LE_RECEIVER_TEST 1 #define HCI_LEN_LE_TRANSMITTER_TEST 3 #define HCI_LEN_LE_TEST_END 0 -/*! \brief New in version 4.1 */ +/* Version 4.1 */ #define HCI_LEN_LE_REM_CONN_PARAM_REP 14 #define HCI_LEN_LE_REM_CONN_PARAM_NEG_REP 3 -/*! \brief New in version 4.2 */ +/* Version 4.2 */ #define HCI_LEN_LE_SET_DATA_LEN 6 #define HCI_LEN_LE_READ_DEF_DATA_LEN 0 #define HCI_LEN_LE_WRITE_DEF_DATA_LEN 4 @@ -554,7 +591,7 @@ extern "C" { #define HCI_LEN_LE_SET_ADDR_RES_ENABLE 1 #define HCI_LEN_LE_SET_RES_PRIV_ADDR_TO 2 #define HCI_LEN_LE_READ_MAX_DATA_LEN 0 -/*! \brief New in version 5.0 */ +/* Version 5.0 */ #define HCI_LEN_LE_READ_PHY 2 #define HCI_LEN_LE_SET_DEF_PHY 3 #define HCI_LEN_LE_SET_PHY 7 @@ -586,7 +623,7 @@ extern "C" { #define HCI_LEN_LE_READ_RF_PATH_COMP 0 #define HCI_LEN_LE_WRITE_RF_PATH_COMP 4 #define HCI_LEN_LE_SET_PRIVACY_MODE 8 -/*! \brief New in version 5.1 */ +/* Version 5.1 */ #define HCI_LEN_LE_SET_CONN_CTE_RX_PARAMS(spLen) (5 + (spLen)) #define HCI_LEN_LE_SET_CONN_CTE_TX_PARAMS(spLen) (4 + (spLen)) #define HCI_LEN_LE_CONN_CTE_REQ_ENABLE 7 @@ -598,6 +635,25 @@ extern "C" { #define HCI_LEN_LE_SET_PAST_PARAM 8 #define HCI_LEN_LE_SET_DEFAULT_PAST_PARAM 6 #define HCI_LEN_LE_GENERATE_DHKEY_V2 65 + +/* Version Milan */ +#define HCI_LEN_LE_SET_CIG_PARAMS(numCis) (15 + (9 * (numCis))) +#define HCI_LEN_LE_CREATE_CIS(numCis) (1 + (4 * (numCis))) +#define HCI_LEN_LE_REMOVE_CIG 1 +#define HCI_LEN_LE_ACCEPT_CIS_REQ 2 +#define HCI_LEN_LE_REJECT_CIS_REQ 3 +#define HCI_LEN_LE_REQUEST_PEER_SCA 2 +#define HCI_LEN_LE_CREATE_BIS (15 + HCI_BC_LEN) +#define HCI_LEN_LE_TERMINATE_BIG 2 +#define HCI_LEN_LE_BIG_CREATE_SYNC(numBis) (8 + HCI_BC_LEN + (numBis)) +#define HCI_LEN_LE_BIG_TERMINATE_SYNC 1 +#define HCI_LEN_LE_SETUP_ISO_DATA_PATH(ccLen) (13 + (ccLen)) +#define HCI_LEN_LE_REMOVE_ISO_DATA_PATH 3 +#define HCI_LEN_LE_ISO_TX_TEST 3 +#define HCI_LEN_LE_ISO_RX_TEST 3 +#define HCI_LEN_LE_ISO_READ_TEST_COUNTERS 2 +#define HCI_LEN_LE_ISO_TEST_END 2 +#define HCI_LEN_LE_SET_HOST_FEATURE 2 /**@}*/ /** \name Events @@ -627,15 +683,15 @@ extern "C" { #define HCI_LE_CONN_UPDATE_CMPL_EVT 0x03 #define HCI_LE_READ_REMOTE_FEAT_CMPL_EVT 0x04 #define HCI_LE_LTK_REQ_EVT 0x05 -/*! \brief New in version 4.1 */ +/* Version 4.1 */ #define HCI_LE_REM_CONN_PARAM_REQ_EVT 0x06 -/*! \brief New in version 4.2 */ +/* Version 4.2 */ #define HCI_LE_DATA_LEN_CHANGE_EVT 0x07 #define HCI_LE_READ_LOCAL_P256_PUB_KEY_CMPL_EVT 0x08 #define HCI_LE_GENERATE_DHKEY_CMPL_EVT 0x09 #define HCI_LE_ENHANCED_CONN_CMPL_EVT 0x0A #define HCI_LE_DIRECT_ADV_REPORT_EVT 0x0B -/*! \brief New in version 5.0 */ +/* Version 5.0 */ #define HCI_LE_PHY_UPDATE_CMPL_EVT 0x0C #define HCI_LE_EXT_ADV_REPORT_EVT 0x0D #define HCI_LE_PER_ADV_SYNC_EST_EVT 0x0E @@ -645,192 +701,225 @@ extern "C" { #define HCI_LE_ADV_SET_TERM_EVT 0x12 #define HCI_LE_SCAN_REQ_RCVD_EVT 0x13 #define HCI_LE_CH_SEL_ALGO_EVT 0x14 -/*! \brief New in version 5.1 */ +/* Version 5.1 */ #define HCI_LE_CONNLESS_IQ_REPORT_EVT 0x15 #define HCI_LE_CONN_IQ_REPORT_EVT 0x16 #define HCI_LE_CTE_REQ_FAILED_EVT 0x17 #define HCI_LE_PER_SYNC_TRSF_RCVD_EVT 0x18 -/*! \brief New in version Milan */ +/* Version 5.2 */ #define HCI_LE_CIS_EST_EVT 0x19 #define HCI_LE_CIS_REQ_EVT 0x1A -#define HCI_LE_BIG_CMPL_EVT 0x1B -#define HCI_LE_BIG_SYNC_LOST_EVT 0x1C -#define HCI_LE_REQ_PEER_SCA_CMPLT_EVT 0x1D +#define HCI_LE_CREATE_BIG_CMPL_EVT 0x1B +#define HCI_LE_TERMINATE_BIG_CMPL_EVT 0x1C +#define HCI_LE_BIG_SYNC_EST_EVT 0x1D +#define HCI_LE_BIG_SYNC_LOST_EVT 0x1E +#define HCI_LE_REQ_PEER_SCA_CMPLT_EVT 0x1F +#define HCI_LE_PATH_LOSS_REPORT_EVT 0x20 +#define HCI_LE_POWER_REPORT_EVT 0x21 +#define HCI_LE_BIG_INFO_ADV_REPORT_EVT 0x22 /**@}*/ /** \name Event parameter lengths * */ /**@{*/ -#define HCI_LEN_DISCONNECT_CMPL 4 /*!< \brief Disconnect event length. */ -#define HCI_LEN_READ_REMOTE_VER_INFO_CMPL 8 /*!< \brief Read remove version info complete event length. */ -#define HCI_LEN_CMD_CMPL 3 /*!< \brief Command complete event length. */ -#define HCI_LEN_CMD_STATUS 4 /*!< \brief Command status event length. */ -#define HCI_LEN_HW_ERR 1 /*!< \brief Hardware error event length. */ -#define HCI_LEN_NUM_CMPL_PKTS 5 /*!< \brief Number of completed packets event length. */ -#define HCI_LEN_ENC_CHANGE 4 /*!< \brief Encryption change event length. */ -#define HCI_LEN_ENC_KEY_REFRESH_CMPL 3 /*!< \brief Encryption key refresh complete event length. */ -#define HCI_LEN_LE_CONN_CMPL 19 /*!< \brief Connection complete event length. */ -#define HCI_LEN_LE_ADV_RPT_MIN 12 /*!< \brief Advertising report event minimum length. */ -#define HCI_LEN_LE_CONN_UPDATE_CMPL 10 /*!< \brief Connection update complete event length. */ -#define HCI_LEN_LE_READ_REMOTE_FEAT_CMPL 12 /*!< \brief Read remote feature event length. */ -#define HCI_LEN_LE_LTK_REQ 13 /*!< \brief LTK request event length. */ -/*! \brief New in version 4.1 */ -#define HCI_LEN_LE_REM_CONN_PARAM_REQ 11 /*!< \brief Remote connection parameter event length. */ -#define HCI_LEN_LE_DATA_LEN_CHANGE 11 /*!< \brief Data length change event length. */ -#define HCI_LEN_LE_READ_PUB_KEY_CMPL 66 /*!< \brief Read local P256 public key compete event length. */ -#define HCI_LEN_LE_GEN_DHKEY_CMPL 34 /*!< \brief Generate DH key complete event length. */ -#define HCI_LEN_LE_ENHANCED_CONN_CMPL 31 /*!< \brief Enhanced connection complete event length. */ -#define HCI_LEN_LE_DIRECT_ADV_REPORT 18 /*!< \brief Direct advertising report event length. */ -#define HCI_LEN_AUTH_PAYLOAD_TIMEOUT 2 /*!< \brief Authenticated payload timeout event length. */ -/*! \brief New in version 5.0 */ -#define HCI_LEN_LE_PHY_UPDATE_CMPL 6 /*!< \brief PHY update complete event length. */ -#define HCI_LEN_LE_CH_SEL_ALGO 4 /*!< \brief Channel selection algorithm event length. */ -#define HCI_LEN_LE_PHY_UPDATE_CMPL 6 /*!< \brief PHY update complete event length. */ -#define HCI_LEN_LE_EXT_ADV_REPORT_MIN 26 /*!< \brief Extended advertising report minimum length. */ -#define HCI_LEN_LE_PER_ADV_SYNC_EST 16 /*!< \brief Periodic advertising sync established event length. */ -#define HCI_LEN_LE_PER_ADV_REPORT 8 /*!< \brief Periodic advertising report event length. */ -#define HCI_LEN_LE_PER_ADV_SYNC_LOST 3 /*!< \brief Periodic advertising sync lost event length. */ -#define HCI_LEN_LE_SCAN_TIMEOUT 1 /*!< \brief Scan timeout event length. */ -#define HCI_LEN_LE_ADV_SET_TERM 6 /*!< \brief Advertising set terminated event length. */ -#define HCI_LEN_LE_SCAN_REQ_RCVD 9 /*!< \brief Scan request received event length. */ -/*! \brief New in version 5.1 */ -#define HCI_LEN_LE_PER_SYNC_TRSF_RCVT 20 /*!< \brief Periodic advertising sync transfer received event length. */ -/*! \brief New in version Milan */ -#define HCI_LEN_LE_CIS_EST 12 /*!< \brief CIS established event length. */ -#define HCI_LEN_LE_CIS_REQ 7 /*!< \brief CIS request event length. */ -#define HCI_LEN_LE_PEER_SCA_CMPL 5 /*!< \brief Request peer SCA complete event length. */ +#define HCI_LEN_DISCONNECT_CMPL 4 /*!< Disconnect event length. */ +#define HCI_LEN_READ_REMOTE_VER_INFO_CMPL 8 /*!< Read remove version info complete event length. */ +#define HCI_LEN_CMD_CMPL 3 /*!< Command complete event length. */ +#define HCI_LEN_CMD_STATUS 4 /*!< Command status event length. */ +#define HCI_LEN_HW_ERR 1 /*!< Hardware error event length. */ +#define HCI_LEN_NUM_CMPL_PKTS(numHdls) (1 + (4 * numHdls)) /*!< Number of completed packets event length. */ +#define HCI_LEN_ENC_CHANGE 4 /*!< Encryption change event length. */ +#define HCI_LEN_ENC_KEY_REFRESH_CMPL 3 /*!< Encryption key refresh complete event length. */ +#define HCI_LEN_LE_CONN_CMPL 19 /*!< Connection complete event length. */ +#define HCI_LEN_LE_ADV_RPT_MIN 12 /*!< Advertising report event minimum length. */ +#define HCI_LEN_LE_CONN_UPDATE_CMPL 10 /*!< Connection update complete event length. */ +#define HCI_LEN_LE_READ_REMOTE_FEAT_CMPL 12 /*!< Read remote feature event length. */ +#define HCI_LEN_LE_LTK_REQ 13 /*!< LTK request event length. */ +/* Version 4.1 */ +#define HCI_LEN_LE_REM_CONN_PARAM_REQ 11 /*!< Remote connection parameter event length. */ +#define HCI_LEN_LE_DATA_LEN_CHANGE 11 /*!< Data length change event length. */ +#define HCI_LEN_LE_READ_PUB_KEY_CMPL 66 /*!< Read local P256 public key compete event length. */ +#define HCI_LEN_LE_GEN_DHKEY_CMPL 34 /*!< Generate DH key complete event length. */ +#define HCI_LEN_LE_ENHANCED_CONN_CMPL 31 /*!< Enhanced connection complete event length. */ +#define HCI_LEN_LE_DIRECT_ADV_REPORT 18 /*!< Direct advertising report event length. */ +#define HCI_LEN_AUTH_PAYLOAD_TIMEOUT 2 /*!< Authenticated payload timeout event length. */ +/* Version 5.0 */ +#define HCI_LEN_LE_PHY_UPDATE_CMPL 6 /*!< PHY update complete event length. */ +#define HCI_LEN_LE_CH_SEL_ALGO 4 /*!< Channel selection algorithm event length. */ +#define HCI_LEN_LE_PHY_UPDATE_CMPL 6 /*!< PHY update complete event length. */ +#define HCI_LEN_LE_EXT_ADV_REPORT_MIN 26 /*!< Extended advertising report minimum length. */ +#define HCI_LEN_LE_PER_ADV_SYNC_EST 16 /*!< Periodic advertising sync established event length. */ +#define HCI_LEN_LE_PER_ADV_REPORT 8 /*!< Periodic advertising report event length. */ +#define HCI_LEN_LE_PER_ADV_SYNC_LOST 3 /*!< Periodic advertising sync lost event length. */ +#define HCI_LEN_LE_SCAN_TIMEOUT 1 /*!< Scan timeout event length. */ +#define HCI_LEN_LE_ADV_SET_TERM 6 /*!< Advertising set terminated event length. */ +#define HCI_LEN_LE_SCAN_REQ_RCVD 9 /*!< Scan request received event length. */ +/* Version 5.1 */ +#define HCI_LEN_LE_PER_SYNC_TRSF_RCVT 20 /*!< Periodic advertising sync transfer received event length. */ +/* Version 5.2 */ +#define HCI_LEN_LE_CIS_EST 29 /*!< CIS established event length. */ +#define HCI_LEN_LE_CIS_REQ 7 /*!< CIS request event length. */ +#define HCI_LEN_LE_PEER_SCA_CMPL 5 /*!< Request peer SCA complete event length. */ +#define HCI_LEN_LE_CREATE_BIG_CMPL(numBis) (19 + (2 * numBis)) /*!< Create BIG complete event length. */ +#define HCI_LEN_LE_TERMINATE_BIG_CMPL 3 /*!< Terminate BIG complete event length. */ +#define HCI_LEN_LE_BIG_SYNC_EST(numBis) (15 + (2 * numBis)) /*!< BIG sync established event length. */ +#define HCI_LEN_LE_BIG_SYNC_LOST 3 /*!< BIG sync lost event length. */ +#define HCI_LEN_LE_POWER_REPORT 9 /*!< Power reporting event length. */ +#define HCI_LEN_LE_PATH_LOSS_ZONE 5 /*!< Path loss reporting event length. */ +#define HCI_LEN_LE_BIG_INFO_ADV_REPORT 20 /*!< BIG Info advertising report length. */ + /**@}*/ /** \name Supported commands * */ /**@{*/ -#define HCI_SUP_DISCONNECT 0x20 /*!< \brief Byte 0 */ -#define HCI_SUP_READ_REMOTE_VER_INFO 0x80 /*!< \brief Byte 2 */ -#define HCI_SUP_SET_EVENT_MASK 0x40 /*!< \brief Byte 5 */ -#define HCI_SUP_RESET 0x80 /*!< \brief Byte 5 */ -#define HCI_SUP_READ_TX_PWR_LVL 0x04 /*!< \brief Byte 10 */ -#define HCI_SUP_READ_LOCAL_VER_INFO 0x08 /*!< \brief Byte 14 */ -#define HCI_SUP_READ_LOCAL_SUP_FEAT 0x20 /*!< \brief Byte 14 */ -#define HCI_SUP_READ_BD_ADDR 0x02 /*!< \brief Byte 15 */ -#define HCI_SUP_READ_RSSI 0x20 /*!< \brief Byte 15 */ -#define HCI_SUP_SET_EVENT_MASK_PAGE2 0x04 /*!< \brief Byte 22 */ -#define HCI_SUP_LE_SET_EVENT_MASK 0x01 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_READ_BUF_SIZE 0x02 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_READ_LOCAL_SUP_FEAT 0x04 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_SET_RAND_ADDR 0x10 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_SET_ADV_PARAM 0x20 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_READ_ADV_TX_POWER 0x40 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_SET_ADV_DATA 0x80 /*!< \brief Byte 25 */ -#define HCI_SUP_LE_SET_SCAN_RESP_DATA 0x01 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_SET_ADV_ENABLE 0x02 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_SET_SCAN_PARAM 0x04 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_SET_SCAN_ENABLE 0x08 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_CREATE_CONN 0x10 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_CREATE_CONN_CANCEL 0x20 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_READ_WHITE_LIST_SIZE 0x40 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_CLEAR_WHITE_LIST 0x80 /*!< \brief Byte 26 */ -#define HCI_SUP_LE_ADD_DEV_WHITE_LIST 0x01 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_REMOVE_DEV_WHITE_LIST 0x02 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_CONN_UPDATE 0x04 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_SET_HOST_CHAN_CLASS 0x08 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_READ_CHAN_MAP 0x10 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_READ_REMOTE_FEAT 0x20 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_ENCRYPT 0x40 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_RAND 0x80 /*!< \brief Byte 27 */ -#define HCI_SUP_LE_START_ENCRYPTION 0x01 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_LTK_REQ_REPL 0x02 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_LTK_REQ_NEG_REPL 0x04 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_READ_SUP_STATES 0x08 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_RECEIVER_TEST 0x10 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_TRANSMITTER_TEST 0x20 /*!< \brief Byte 28 */ -#define HCI_SUP_LE_TEST_END 0x40 /*!< \brief Byte 28 */ -#define HCI_SUP_READ_AUTH_PAYLOAD_TO 0x10 /*!< \brief Byte 32 */ -#define HCI_SUP_WRITE_AUTH_PAYLOAD_TO 0x20 /*!< \brief Byte 32 */ -/*! \brief New in version 4.1 */ -#define HCI_SUP_LE_REM_CONN_PARAM_REQ_REPL 0x10 /*!< \brief Byte 33 */ -#define HCI_SUP_LE_REM_CONN_PARAM_REQ_NEG_REPL 0x20 /*!< \brief Byte 33 */ -/*! \brief New in version 4.2 */ -#define HCI_SUP_LE_SET_DATA_LEN 0x40 /*!< \brief Byte 33 */ -#define HCI_SUP_LE_READ_DEF_DATA_LEN 0x80 /*!< \brief Byte 33 */ -#define HCI_SUP_LE_WRITE_DEF_DATA_LEN 0x01 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_READ_LOCAL_P256_PUB_KEY 0x02 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_GENERATE_DHKEY 0x04 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_ADD_DEV_RES_LIST_EVT 0x08 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_REMOVE_DEV_RES_LIST 0x10 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_CLEAR_RES_LIST 0x20 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_READ_RES_LIST_SIZE 0x40 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_READ_PEER_RES_ADDR 0x80 /*!< \brief Byte 34 */ -#define HCI_SUP_LE_READ_LOCAL_RES_ADDR 0x01 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_SET_ADDR_RES_ENABLE 0x02 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_SET_RES_PRIV_ADDR_TO 0x04 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_READ_MAX_DATA_LEN 0x08 /*!< \brief Byte 35 */ -/*! \brief New in version 5.0 */ -#define HCI_SUP_LE_READ_PHY 0x10 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_SET_DEF_PHY 0x20 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_SET_PHY 0x40 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_ENHANCED_RECEIVER_TEST 0x80 /*!< \brief Byte 35 */ -#define HCI_SUP_LE_ENHANCED_TRANSMITTER_TEST 0x01 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_SET_ADV_SET_RAND_ADDR 0x02 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_SET_EXT_ADV_PARAM 0x04 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_SET_EXT_ADV_DATA 0x08 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_SET_EXT_SCAN_RESP_DATA 0x10 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_SET_EXT_ADV_ENABLE 0x20 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_READ_MAX_ADV_DATA_LEN 0x40 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_READ_NUM_OF_SUP_ADV_SETS 0x80 /*!< \brief Byte 36 */ -#define HCI_SUP_LE_REMOVE_ADV_SET 0x01 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_CLEAR_ADV_SETS 0x02 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_SET_PER_ADV_PARAM 0x04 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_SET_PER_ADV_DATA 0x08 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_SET_PER_ADV_ENABLE 0x10 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_SET_EXT_SCAN_PARAM 0x20 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_SET_EXT_SCAN_ENABLE 0x40 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_EXT_CREATE_CONN 0x80 /*!< \brief Byte 37 */ -#define HCI_SUP_LE_PER_ADV_CREATE_SYNC 0x01 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_PER_ADV_CREATE_SYNC_CANCEL 0x02 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_PER_ADV_TERMINATE_SYNC 0x04 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_ADD_DEV_PER_ADV_LIST 0x08 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_REMOVE_DEV_PER_ADV_LIST 0x10 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_CLEAR_PER_ADV_LIST 0x20 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_READ_PER_ADV_LIST_SIZE 0x40 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_READ_TX_POWER 0x80 /*!< \brief Byte 38 */ -#define HCI_SUP_LE_READ_RF_PATH_COMP 0x01 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_WRITE_RF_PATH_COMP 0x02 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_SET_PRIVACY_MODE 0x04 /*!< \brief Byte 39 */ -/*! \brief New in version 5.1 */ -#define HCI_SUP_LE_RECEIVER_TEST_V3 0x08 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_TRANSMITTER_TEST_V3 0x10 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_SET_CONNLESS_CTE_TX_PARAMS 0x20 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_SET_CONNLESS_CTE_TX_ENABLE 0x40 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_SET_CONNLESS_IQ_SAMP_ENABLE 0x80 /*!< \brief Byte 39 */ -#define HCI_SUP_LE_SET_CONN_CTE_RX_PARAMS 0x01 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_SET_CONN_CTE_TX_PARAMS 0x02 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_CONN_CTE_REQ_ENABLE 0x04 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_CONN_CTE_RSP_ENABLE 0x08 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_READ_ANTENNA_INFO 0x10 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_SET_PER_ADV_RCV_ENABLE 0x20 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_PER_ADV_SYNC_TRANSFER 0x40 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_PER_ADV_SET_INFO_TRANSFER 0x80 /*!< \brief Byte 40 */ -#define HCI_SUP_LE_SET_PAST_PARAM 0x01 /*!< \brief Byte 41 */ -#define HCI_SUP_LE_SET_DEFAULT_PAST_PARAM 0x02 /*!< \brief Byte 41 */ -#define HCI_SUP_LE_GENERATE_DHKEY_V2 0x04 /*!< \brief Byte 41 */ -#define HCI_SUP_LE_MODIFY_SLEEP_CLK_ACCURACY 0x10 /*!< \brief Byte 41 */ -/*! \brief New in version Milan */ -#define HCI_SUP_LE_READ_BUF_SIZE_V2 0x01 /*!< \brief Byte 42 */ -#define HCI_SUP_LE_SET_CIG_PARAM 0x02 /*!< \brief Byte 42 */ -#define HCI_SUP_LE_CREATE_CIS 0x04 /*!< \brief Byte 42 */ -#define HCI_SUP_LE_REMOVE_CIG 0x08 /*!< \brief Byte 42 */ -#define HCI_SUP_LE_ACCEPT_CIS_REQ 0x01 /*!< \brief Byte 43 */ -#define HCI_SUP_LE_REJECT_CIS_REQ 0x02 /*!< \brief Byte 43 */ -#define HCI_SUP_LE_CREATE_BIG 0x04 /*!< \brief Byte 43 */ -#define HCI_SUP_LE_BIG_CREATE_SYNC 0x08 /*!< \brief Byte 43 */ -#define HCI_SUP_LE_TERMINATE_BIG 0x01 /*!< \brief Byte 44 */ -#define HCI_SUP_LE_SETUP_ISO_DATA_PATH 0x02 /*!< \brief Byte 44 */ -#define HCI_SUP_LE_REMOVE_ISO_DATA_PATH 0x04 /*!< \brief Byte 44 */ -#define HCI_SUP_LE_REQ_PEER_SCA 0x08 /*!< \brief Byte 44 */ - -#define HCI_SUP_CMD_LEN 64 /*!< \brief Byte length of support cmd field. */ +#define HCI_SUP_DISCONNECT 0x20 /*!< Byte 0 */ +#define HCI_SUP_READ_REMOTE_VER_INFO 0x80 /*!< Byte 2 */ +#define HCI_SUP_SET_EVENT_MASK 0x40 /*!< Byte 5 */ +#define HCI_SUP_RESET 0x80 /*!< Byte 5 */ +#define HCI_SUP_READ_TX_PWR_LVL 0x04 /*!< Byte 10 */ +#define HCI_SUP_READ_LOCAL_VER_INFO 0x08 /*!< Byte 14 */ +#define HCI_SUP_READ_LOCAL_SUP_FEAT 0x20 /*!< Byte 14 */ +#define HCI_SUP_READ_BD_ADDR 0x02 /*!< Byte 15 */ +#define HCI_SUP_READ_RSSI 0x20 /*!< Byte 15 */ +#define HCI_SUP_SET_EVENT_MASK_PAGE2 0x04 /*!< Byte 22 */ +#define HCI_SUP_LE_SET_EVENT_MASK 0x01 /*!< Byte 25 */ +#define HCI_SUP_LE_READ_BUF_SIZE 0x02 /*!< Byte 25 */ +#define HCI_SUP_LE_READ_LOCAL_SUP_FEAT 0x04 /*!< Byte 25 */ +#define HCI_SUP_LE_SET_RAND_ADDR 0x10 /*!< Byte 25 */ +#define HCI_SUP_LE_SET_ADV_PARAM 0x20 /*!< Byte 25 */ +#define HCI_SUP_LE_READ_ADV_TX_POWER 0x40 /*!< Byte 25 */ +#define HCI_SUP_LE_SET_ADV_DATA 0x80 /*!< Byte 25 */ +#define HCI_SUP_LE_SET_SCAN_RESP_DATA 0x01 /*!< Byte 26 */ +#define HCI_SUP_LE_SET_ADV_ENABLE 0x02 /*!< Byte 26 */ +#define HCI_SUP_LE_SET_SCAN_PARAM 0x04 /*!< Byte 26 */ +#define HCI_SUP_LE_SET_SCAN_ENABLE 0x08 /*!< Byte 26 */ +#define HCI_SUP_LE_CREATE_CONN 0x10 /*!< Byte 26 */ +#define HCI_SUP_LE_CREATE_CONN_CANCEL 0x20 /*!< Byte 26 */ +#define HCI_SUP_LE_READ_WHITE_LIST_SIZE 0x40 /*!< Byte 26 */ +#define HCI_SUP_LE_CLEAR_WHITE_LIST 0x80 /*!< Byte 26 */ +#define HCI_SUP_LE_ADD_DEV_WHITE_LIST 0x01 /*!< Byte 27 */ +#define HCI_SUP_LE_REMOVE_DEV_WHITE_LIST 0x02 /*!< Byte 27 */ +#define HCI_SUP_LE_CONN_UPDATE 0x04 /*!< Byte 27 */ +#define HCI_SUP_LE_SET_HOST_CHAN_CLASS 0x08 /*!< Byte 27 */ +#define HCI_SUP_LE_READ_CHAN_MAP 0x10 /*!< Byte 27 */ +#define HCI_SUP_LE_READ_REMOTE_FEAT 0x20 /*!< Byte 27 */ +#define HCI_SUP_LE_ENCRYPT 0x40 /*!< Byte 27 */ +#define HCI_SUP_LE_RAND 0x80 /*!< Byte 27 */ +#define HCI_SUP_LE_START_ENCRYPTION 0x01 /*!< Byte 28 */ +#define HCI_SUP_LE_LTK_REQ_REPL 0x02 /*!< Byte 28 */ +#define HCI_SUP_LE_LTK_REQ_NEG_REPL 0x04 /*!< Byte 28 */ +#define HCI_SUP_LE_READ_SUP_STATES 0x08 /*!< Byte 28 */ +#define HCI_SUP_LE_RECEIVER_TEST 0x10 /*!< Byte 28 */ +#define HCI_SUP_LE_TRANSMITTER_TEST 0x20 /*!< Byte 28 */ +#define HCI_SUP_LE_TEST_END 0x40 /*!< Byte 28 */ +#define HCI_SUP_READ_AUTH_PAYLOAD_TO 0x10 /*!< Byte 32 */ +#define HCI_SUP_WRITE_AUTH_PAYLOAD_TO 0x20 /*!< Byte 32 */ +/* Version 4.1 */ +#define HCI_SUP_LE_REM_CONN_PARAM_REQ_REPL 0x10 /*!< Byte 33 */ +#define HCI_SUP_LE_REM_CONN_PARAM_REQ_NEG_REPL 0x20 /*!< Byte 33 */ +/* Version 4.2 */ +#define HCI_SUP_LE_SET_DATA_LEN 0x40 /*!< Byte 33 */ +#define HCI_SUP_LE_READ_DEF_DATA_LEN 0x80 /*!< Byte 33 */ +#define HCI_SUP_LE_WRITE_DEF_DATA_LEN 0x01 /*!< Byte 34 */ +#define HCI_SUP_LE_READ_LOCAL_P256_PUB_KEY 0x02 /*!< Byte 34 */ +#define HCI_SUP_LE_GENERATE_DHKEY 0x04 /*!< Byte 34 */ +#define HCI_SUP_LE_ADD_DEV_RES_LIST_EVT 0x08 /*!< Byte 34 */ +#define HCI_SUP_LE_REMOVE_DEV_RES_LIST 0x10 /*!< Byte 34 */ +#define HCI_SUP_LE_CLEAR_RES_LIST 0x20 /*!< Byte 34 */ +#define HCI_SUP_LE_READ_RES_LIST_SIZE 0x40 /*!< Byte 34 */ +#define HCI_SUP_LE_READ_PEER_RES_ADDR 0x80 /*!< Byte 34 */ +#define HCI_SUP_LE_READ_LOCAL_RES_ADDR 0x01 /*!< Byte 35 */ +#define HCI_SUP_LE_SET_ADDR_RES_ENABLE 0x02 /*!< Byte 35 */ +#define HCI_SUP_LE_SET_RES_PRIV_ADDR_TO 0x04 /*!< Byte 35 */ +#define HCI_SUP_LE_READ_MAX_DATA_LEN 0x08 /*!< Byte 35 */ +/* Version 5.0 */ +#define HCI_SUP_LE_READ_PHY 0x10 /*!< Byte 35 */ +#define HCI_SUP_LE_SET_DEF_PHY 0x20 /*!< Byte 35 */ +#define HCI_SUP_LE_SET_PHY 0x40 /*!< Byte 35 */ +#define HCI_SUP_LE_ENHANCED_RECEIVER_TEST 0x80 /*!< Byte 35 */ +#define HCI_SUP_LE_ENHANCED_TRANSMITTER_TEST 0x01 /*!< Byte 36 */ +#define HCI_SUP_LE_SET_ADV_SET_RAND_ADDR 0x02 /*!< Byte 36 */ +#define HCI_SUP_LE_SET_EXT_ADV_PARAM 0x04 /*!< Byte 36 */ +#define HCI_SUP_LE_SET_EXT_ADV_DATA 0x08 /*!< Byte 36 */ +#define HCI_SUP_LE_SET_EXT_SCAN_RESP_DATA 0x10 /*!< Byte 36 */ +#define HCI_SUP_LE_SET_EXT_ADV_ENABLE 0x20 /*!< Byte 36 */ +#define HCI_SUP_LE_READ_MAX_ADV_DATA_LEN 0x40 /*!< Byte 36 */ +#define HCI_SUP_LE_READ_NUM_OF_SUP_ADV_SETS 0x80 /*!< Byte 36 */ +#define HCI_SUP_LE_REMOVE_ADV_SET 0x01 /*!< Byte 37 */ +#define HCI_SUP_LE_CLEAR_ADV_SETS 0x02 /*!< Byte 37 */ +#define HCI_SUP_LE_SET_PER_ADV_PARAM 0x04 /*!< Byte 37 */ +#define HCI_SUP_LE_SET_PER_ADV_DATA 0x08 /*!< Byte 37 */ +#define HCI_SUP_LE_SET_PER_ADV_ENABLE 0x10 /*!< Byte 37 */ +#define HCI_SUP_LE_SET_EXT_SCAN_PARAM 0x20 /*!< Byte 37 */ +#define HCI_SUP_LE_SET_EXT_SCAN_ENABLE 0x40 /*!< Byte 37 */ +#define HCI_SUP_LE_EXT_CREATE_CONN 0x80 /*!< Byte 37 */ +#define HCI_SUP_LE_PER_ADV_CREATE_SYNC 0x01 /*!< Byte 38 */ +#define HCI_SUP_LE_PER_ADV_CREATE_SYNC_CANCEL 0x02 /*!< Byte 38 */ +#define HCI_SUP_LE_PER_ADV_TERMINATE_SYNC 0x04 /*!< Byte 38 */ +#define HCI_SUP_LE_ADD_DEV_PER_ADV_LIST 0x08 /*!< Byte 38 */ +#define HCI_SUP_LE_REMOVE_DEV_PER_ADV_LIST 0x10 /*!< Byte 38 */ +#define HCI_SUP_LE_CLEAR_PER_ADV_LIST 0x20 /*!< Byte 38 */ +#define HCI_SUP_LE_READ_PER_ADV_LIST_SIZE 0x40 /*!< Byte 38 */ +#define HCI_SUP_LE_READ_TX_POWER 0x80 /*!< Byte 38 */ +#define HCI_SUP_LE_READ_RF_PATH_COMP 0x01 /*!< Byte 39 */ +#define HCI_SUP_LE_WRITE_RF_PATH_COMP 0x02 /*!< Byte 39 */ +#define HCI_SUP_LE_SET_PRIVACY_MODE 0x04 /*!< Byte 39 */ +/* Version 5.1 */ +#define HCI_SUP_LE_RECEIVER_TEST_V3 0x08 /*!< Byte 39 */ +#define HCI_SUP_LE_TRANSMITTER_TEST_V3 0x10 /*!< Byte 39 */ +#define HCI_SUP_LE_SET_CONNLESS_CTE_TX_PARAMS 0x20 /*!< Byte 39 */ +#define HCI_SUP_LE_SET_CONNLESS_CTE_TX_ENABLE 0x40 /*!< Byte 39 */ +#define HCI_SUP_LE_SET_CONNLESS_IQ_SAMP_ENABLE 0x80 /*!< Byte 39 */ +#define HCI_SUP_LE_SET_CONN_CTE_RX_PARAMS 0x01 /*!< Byte 40 */ +#define HCI_SUP_LE_SET_CONN_CTE_TX_PARAMS 0x02 /*!< Byte 40 */ +#define HCI_SUP_LE_CONN_CTE_REQ_ENABLE 0x04 /*!< Byte 40 */ +#define HCI_SUP_LE_CONN_CTE_RSP_ENABLE 0x08 /*!< Byte 40 */ +#define HCI_SUP_LE_READ_ANTENNA_INFO 0x10 /*!< Byte 40 */ +#define HCI_SUP_LE_SET_PER_ADV_RCV_ENABLE 0x20 /*!< Byte 40 */ +#define HCI_SUP_LE_PER_ADV_SYNC_TRANSFER 0x40 /*!< Byte 40 */ +#define HCI_SUP_LE_PER_ADV_SET_INFO_TRANSFER 0x80 /*!< Byte 40 */ +#define HCI_SUP_LE_SET_PAST_PARAM 0x01 /*!< Byte 41 */ +#define HCI_SUP_LE_SET_DEFAULT_PAST_PARAM 0x02 /*!< Byte 41 */ +#define HCI_SUP_LE_GENERATE_DHKEY_V2 0x04 /*!< Byte 41 */ +#define HCI_SUP_LE_MODIFY_SLEEP_CLK_ACCURACY 0x10 /*!< Byte 41 */ +/* Version 5.2 */ +#define HCI_SUP_LE_READ_BUF_SIZE_V2 0x20 /*!< Byte 41 */ +#define HCI_SUP_LE_READ_ISO_TX_SYNC 0x40 /*!< Byte 41 */ +#define HCI_SUP_LE_SET_CIG_PARAM 0x80 /*!< Byte 41 */ +#define HCI_SUP_LE_SET_CIG_PARAM_TEST 0x01 /*!< Byte 42 */ +#define HCI_SUP_LE_CREATE_CIS 0x02 /*!< Byte 42 */ +#define HCI_SUP_LE_REMOVE_CIG 0x04 /*!< Byte 42 */ +#define HCI_SUP_LE_ACCEPT_CIS_REQ 0x08 /*!< Byte 42 */ +#define HCI_SUP_LE_REJECT_CIS_REQ 0x10 /*!< Byte 42 */ +#define HCI_SUP_LE_CREATE_BIG 0x20 /*!< Byte 42 */ +#define HCI_SUP_LE_CREATE_BIG_TEST 0x40 /*!< Byte 42 */ +#define HCI_SUP_LE_TERMINATE_BIG 0x80 /*!< Byte 42 */ +#define HCI_SUP_LE_BIG_CREATE_SYNC 0x01 /*!< Byte 43 */ +#define HCI_SUP_LE_BIG_TERMINATE_SYNC 0x02 /*!< Byte 43 */ +#define HCI_SUP_LE_REQ_PEER_SCA 0x04 /*!< Byte 43 */ +#define HCI_SUP_LE_SETUP_ISO_DATA_PATH 0x08 /*!< Byte 43 */ +#define HCI_SUP_LE_REMOVE_ISO_DATA_PATH 0x10 /*!< Byte 43 */ +#define HCI_SUP_LE_ISO_TRANSMIT_TEST 0x20 /*!< Byte 43 */ +#define HCI_SUP_LE_ISO_RECEIVE_TEST 0x40 /*!< Byte 43 */ +#define HCI_SUP_LE_ISO_READ_TEST_COUNTERS 0x80 /*!< Byte 43 */ +#define HCI_SUP_LE_ISO_TEST_END 0x01 /*!< Byte 44 */ +#define HCI_SUP_LE_SET_HOST_FEATURE 0x02 /*!< Byte 44 */ +#define HCI_SUP_LE_READ_ISO_LINK_QUALITY 0x04 /*!< Byte 44 */ +#define HCI_SUP_LE_ENH_READ_TX_POWER_LEVEL 0x08 /*!< Byte 44 */ +#define HCI_SUP_LE_READ_REMOTE_TX_POWER_LEVEL 0x01 /*!< Byte 44 */ +#define HCI_SUP_LE_SET_PATH_LOSS_REPORT_PARAM 0x02 /*!< Byte 44 */ +#define HCI_SUP_LE_SET_PATH_LOSS_REPORT_ENABLE 0x04 /*!< Byte 44 */ +#define HCI_SUP_LE_SET_TX_POWER_REPORT_ENABLE 0x08 /*!< Byte 44 */ +#define HCI_SUP_LE_TRANSMITTER_TEST_V4 0x01 /*!< Byte 45 */ +#define HCI_SUP_READ_LOCAL_SUP_CODECS_V2 0x02 /*!< Byte 45 */ +#define HCI_SUP_READ_LOCAL_SUP_CODEC_CAP 0x04 /*!< Byte 45 */ +#define HCI_SUP_READ_LOCAL_SUP_CTR_DLY 0x08 /*!< Byte 45 */ +#define HCI_SUP_CONFIG_DATA_PATH 0x10 /*!< Byte 45 */ + +#define HCI_SUP_CMD_LEN 64 /*!< Byte length of support cmd field. */ /**@}*/ @@ -838,328 +927,355 @@ extern "C" { * */ /**@{*/ -#define HCI_EVT_MASK_DISCONNECT_CMPL 0x10 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_ENC_CHANGE 0x80 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_READ_REMOTE_VER_INFO_CMPL 0x08 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_HW_ERROR 0x80 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_DATA_BUF_OVERFLOW 0x02 /*!< \brief Byte 3 */ -#define HCI_EVT_MASK_ENC_KEY_REFRESH_CMPL 0x80 /*!< \brief Byte 5 */ -#define HCI_EVT_MASK_LE_META 0x20 /*!< \brief Byte 7 */ +#define HCI_EVT_MASK_DISCONNECT_CMPL 0x10 /*!< Byte 0 */ +#define HCI_EVT_MASK_ENC_CHANGE 0x80 /*!< Byte 0 */ +#define HCI_EVT_MASK_READ_REMOTE_VER_INFO_CMPL 0x08 /*!< Byte 1 */ +#define HCI_EVT_MASK_HW_ERROR 0x80 /*!< Byte 1 */ +#define HCI_EVT_MASK_DATA_BUF_OVERFLOW 0x02 /*!< Byte 3 */ +#define HCI_EVT_MASK_ENC_KEY_REFRESH_CMPL 0x80 /*!< Byte 5 */ +#define HCI_EVT_MASK_LE_META 0x20 /*!< Byte 7 */ /**@}*/ /** \name Event mask page 2 * */ /**@{*/ -#define HCI_EVT_MASK_AUTH_PAYLOAD_TIMEOUT 0x80 /*!< \brief Byte 2 */ +#define HCI_EVT_MASK_AUTH_PAYLOAD_TIMEOUT 0x80 /*!< Byte 2 */ /**@}*/ /** \name LE event mask * */ /**@{*/ -#define HCI_EVT_MASK_LE_CONN_CMPL_EVT 0x01 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_ADV_REPORT_EVT 0x02 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_CONN_UPDATE_CMPL_EVT 0x04 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_READ_REMOTE_FEAT_CMPL_EVT 0x08 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_LTK_REQ_EVT 0x10 /*!< \brief Byte 0 */ -/*! \brief New in version 4.1 */ -#define HCI_EVT_MASK_LE_REMOTE_CONN_PARAM_REQ_EVT 0x20 /*!< \brief Byte 0 */ -/*! \brief New in version 4.2 */ -#define HCI_EVT_MASK_LE_DATA_LEN_CHANGE_EVT 0x40 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_READ_LOCAL_P256_PUB_KEY_CMPL 0x80 /*!< \brief Byte 0 */ -#define HCI_EVT_MASK_LE_GENERATE_DHKEY_CMPL 0x01 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_ENHANCED_CONN_CMPL_EVT 0x02 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_DIRECT_ADV_REPORT_EVT 0x04 /*!< \brief Byte 1 */ -/*! \brief New in version 5.0 */ -#define HCI_EVT_MASK_LE_PHY_UPDATE_CMPL_EVT 0x08 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_EXT_ADV_REPORT_EVT 0x10 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_PER_ADV_SYNC_EST_EVT 0x20 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_PER_ADV_REPORT_EVT 0x40 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_PER_ADV_SYNC_LOST_EVT 0x80 /*!< \brief Byte 1 */ -#define HCI_EVT_MASK_LE_SCAN_TIMEOUT_EVT 0x01 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_ADV_SET_TERM_EVT 0x02 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_SCAN_REQ_RCVD_EVT 0x04 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_CH_SEL_ALGO_EVT 0x08 /*!< \brief Byte 2 (Bit 19) */ -/*! \brief New in version 5.1 */ -#define HCI_EVT_MASK_LE_CONNLESS_IQ_REPORT_EVT 0x10 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_CONN_IQ_REPORT_EVT 0x20 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_CTE_REQ_FAILED_EVT 0x40 /*!< \brief Byte 2 */ -#define HCI_EVT_MASK_LE_PER_SYNC_TRSF_RCVT_EVT 0x80 /*!< \brief Byte 2 (Bit 23) */ -/*! \brief New in version Milan */ -#define HCI_EVT_MASK_LE_CIS_EST_EVT 0x01 /*!< \brief Byte 3 */ -#define HCI_EVT_MASK_LE_CIS_REQ_EVT 0x02 /*!< \brief Byte 3 */ -#define HCI_EVT_MASK_LE_BIG_CMPL_EVT 0x04 /*!< \brief Byte 3 */ -#define HCI_EVT_MASK_LE_BIG_SYNC_LOST_EVT 0x08 /*!< \brief Byte 3 */ -#define HCI_EVT_MASK_LE_PEER_SCA_CMPL_EVT 0x10 /*!< \brief Byte 3 */ +#define HCI_EVT_MASK_LE_CONN_CMPL_EVT 0x01 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_ADV_REPORT_EVT 0x02 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_CONN_UPDATE_CMPL_EVT 0x04 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_READ_REMOTE_FEAT_CMPL_EVT 0x08 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_LTK_REQ_EVT 0x10 /*!< Byte 0 */ +/* Version 4.1 */ +#define HCI_EVT_MASK_LE_REMOTE_CONN_PARAM_REQ_EVT 0x20 /*!< Byte 0 */ +/* Version 4.2 */ +#define HCI_EVT_MASK_LE_DATA_LEN_CHANGE_EVT 0x40 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_READ_LOCAL_P256_PUB_KEY_CMPL 0x80 /*!< Byte 0 */ +#define HCI_EVT_MASK_LE_GENERATE_DHKEY_CMPL 0x01 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_ENHANCED_CONN_CMPL_EVT 0x02 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_DIRECT_ADV_REPORT_EVT 0x04 /*!< Byte 1 */ +/* Version 5.0 */ +#define HCI_EVT_MASK_LE_PHY_UPDATE_CMPL_EVT 0x08 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_EXT_ADV_REPORT_EVT 0x10 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_PER_ADV_SYNC_EST_EVT 0x20 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_PER_ADV_REPORT_EVT 0x40 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_PER_ADV_SYNC_LOST_EVT 0x80 /*!< Byte 1 */ +#define HCI_EVT_MASK_LE_SCAN_TIMEOUT_EVT 0x01 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_ADV_SET_TERM_EVT 0x02 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_SCAN_REQ_RCVD_EVT 0x04 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_CH_SEL_ALGO_EVT 0x08 /*!< Byte 2 (Bit 19) */ +/* Version 5.1 */ +#define HCI_EVT_MASK_LE_CONNLESS_IQ_REPORT_EVT 0x10 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_CONN_IQ_REPORT_EVT 0x20 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_CTE_REQ_FAILED_EVT 0x40 /*!< Byte 2 */ +#define HCI_EVT_MASK_LE_PER_SYNC_TRSF_RCVT_EVT 0x80 /*!< Byte 2 (Bit 23) */ +/* Version 5.2 */ +#define HCI_EVT_MASK_LE_CIS_EST_EVT 0x01 /*!< Byte 3 (Bit 24) */ +#define HCI_EVT_MASK_LE_CIS_REQ_EVT 0x02 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_CREATE_BIG_CMPL_EVT 0x04 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_TERMINATE_BIG_CMPL_EVT 0x08 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_BIG_SYNC_EST_EVT 0x10 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_BIG_SYNC_LOST_EVT 0x20 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_PEER_SCA_CMPL_EVT 0x40 /*!< Byte 3 */ +#define HCI_EVT_MASK_LE_PATH_LOSS_REPORT_EVT 0x80 /*!< Byte 3 */ + +#define HCI_EVT_MASK_LE_TX_POWER_REPORT_EVT 0x01 /*!< Byte 4 (Bit 32)*/ +#define HCI_EVT_MASK_LE_BIG_INFO_ADV_RPT_EVT 0x02 /*!< Byte 4 */ + /**@}*/ /** \name LE supported features * */ /**@{*/ -/*! \brief New in version 4.0 */ -#define HCI_LE_SUP_FEAT_ENCRYPTION 0x00000001 /*!< \brief Encryption supported */ -/*! \brief New in version 4.1 */ -#define HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC 0x00000002 /*!< \brief Connection Parameters Request Procedure supported */ -#define HCI_LE_SUP_FEAT_EXT_REJECT_IND 0x00000004 /*!< \brief Extended Reject Indication supported */ -#define HCI_LE_SUP_FEAT_SLV_INIT_FEAT_EXCH 0x00000008 /*!< \brief Slave-Initiated Features Exchange supported */ -#define HCI_LE_SUP_FEAT_LE_PING 0x00000010 /*!< \brief LE Ping supported */ -/*! \brief New in version 4.2 */ -#define HCI_LE_SUP_FEAT_DATA_LEN_EXT 0x00000020 /*!< \brief Data Length Extension supported */ -#define HCI_LE_SUP_FEAT_PRIVACY 0x00000040 /*!< \brief LL Privacy supported */ -#define HCI_LE_SUP_FEAT_EXT_SCAN_FILT_POLICY 0x00000080 /*!< \brief Extended Scan Filter Policy supported */ -/*! \brief New in version 5.0 */ -#define HCI_LE_SUP_FEAT_LE_2M_PHY 0x00000100 /*!< \brief LE 2M PHY supported */ -#define HCI_LE_SUP_FEAT_STABLE_MOD_IDX_TRANSMITTER 0x00000200 /*!< \brief Stable Modulation Index - Transmitter supported */ -#define HCI_LE_SUP_FEAT_STABLE_MOD_IDX_RECEIVER 0x00000400 /*!< \brief Stable Modulation Index - Receiver supported */ -#define HCI_LE_SUP_FEAT_LE_CODED_PHY 0x00000800 /*!< \brief LE Coded PHY supported */ -#define HCI_LE_SUP_FEAT_LE_EXT_ADV 0x00001000 /*!< \brief LE Extended Advertising supported */ -#define HCI_LE_SUP_FEAT_LE_PER_ADV 0x00002000 /*!< \brief LE Periodic Advertising supported */ -#define HCI_LE_SUP_FEAT_CH_SEL_2 0x00004000 /*!< \brief Channel Selection Algorithm #2 supported */ -#define HCI_LE_SUP_FEAT_LE_POWER_CLASS_1 0x00008000 /*!< \brief LE Power Class 1 supported */ -#define HCI_LE_SUP_FEAT_MIN_NUN_USED_CHAN 0x00010000 /*!< \brief Minimum Number of Used Channels Procedure supported */ -/*! \brief New in version 5.1 */ -#define HCI_LE_SUP_FEAT_CONN_CTE_REQ 0x00020000 /*!< \brief Connection CTE Request supported */ -#define HCI_LE_SUP_FEAT_CONN_CTE_RSP 0x00040000 /*!< \brief Connection CTE Response supported */ -#define HCI_LE_SUP_FEAT_CONNLESS_CTE_TRANS 0x00080000 /*!< \brief Connectionless CTE Transmitter supported */ -#define HCI_LE_SUP_FEAT_CONNLESS_CTE_RECV 0x00100000 /*!< \brief Connectionless CTE Receiver supported */ -#define HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOD 0x00200000 /*!< \brief Anetenna Switching during CTE Transmission (AoD) supported */ -#define HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOA 0x00400000 /*!< \brief Anetenna Switching during CTE Reception (AoA) supported */ -#define HCI_LE_SUP_FEAT_RECV_CTE 0x00800000 /*!< \brief Receive Constant Tone Extension supported */ -#define HCI_LE_SUP_FEAT_PAST_SENDER 0x01000000 /*!< \brief Periodic Advertising Sync Transfer Sender supported */ -#define HCI_LE_SUP_FEAT_PAST_RECIPIENT 0x02000000 /*!< \brief Periodic Advertising Sync Transfer Recipient supported */ -#define HCI_LE_SUP_FEAT_SCA_UPDATE 0x04000000 /*!< \brief Sleep Clock Accuracy Update supported */ -#define HCI_LE_SUP_FEAT_REMOTE_PUB_KEY_VALIDATION 0x08000000 /*!< \brief Remote Public Key Validation supported */ -/*! \brief New in version Milan */ -#define HCI_LE_SUP_FEAT_CIS_MASTER 0x10000000 /*!< \brief Connected Isochronous Master Role supported */ -#define HCI_LE_SUP_FEAT_CIS_SLAVE 0x20000000 /*!< \brief Connected Isochronous Slave Role supported */ -#define HCI_LE_SUP_FEAT_ISO_BROADCASTER 0x40000000 /*!< \brief Isochronous Broadcaster Role supported */ -#define HCI_LE_SUP_FEAT_ISO_SYNC 0x80000000 /*!< \brief Isochronous Synchronizer Role supported */ +/* Version 4.0 */ +#define HCI_LE_SUP_FEAT_ENCRYPTION 0x0000000000000001 /*!< Encryption supported */ +/* Version 4.1 */ +#define HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC 0x0000000000000002 /*!< Connection Parameters Request Procedure supported */ +#define HCI_LE_SUP_FEAT_EXT_REJECT_IND 0x0000000000000004 /*!< Extended Reject Indication supported */ +#define HCI_LE_SUP_FEAT_SLV_INIT_FEAT_EXCH 0x0000000000000008 /*!< Slave-Initiated Features Exchange supported */ +#define HCI_LE_SUP_FEAT_LE_PING 0x0000000000000010 /*!< LE Ping supported */ +/* Version 4.2 */ +#define HCI_LE_SUP_FEAT_DATA_LEN_EXT 0x0000000000000020 /*!< Data Length Extension supported */ +#define HCI_LE_SUP_FEAT_PRIVACY 0x0000000000000040 /*!< LL Privacy supported */ +#define HCI_LE_SUP_FEAT_EXT_SCAN_FILT_POLICY 0x0000000000000080 /*!< Extended Scan Filter Policy supported */ +/* Version 5.0 */ +#define HCI_LE_SUP_FEAT_LE_2M_PHY 0x0000000000000100 /*!< LE 2M PHY supported */ +#define HCI_LE_SUP_FEAT_STABLE_MOD_IDX_TRANSMITTER 0x0000000000000200 /*!< Stable Modulation Index - Transmitter supported */ +#define HCI_LE_SUP_FEAT_STABLE_MOD_IDX_RECEIVER 0x0000000000000400 /*!< Stable Modulation Index - Receiver supported */ +#define HCI_LE_SUP_FEAT_LE_CODED_PHY 0x0000000000000800 /*!< LE Coded PHY supported */ +#define HCI_LE_SUP_FEAT_LE_EXT_ADV 0x0000000000001000 /*!< LE Extended Advertising supported */ +#define HCI_LE_SUP_FEAT_LE_PER_ADV 0x0000000000002000 /*!< LE Periodic Advertising supported */ +#define HCI_LE_SUP_FEAT_CH_SEL_2 0x0000000000004000 /*!< Channel Selection Algorithm #2 supported */ +#define HCI_LE_SUP_FEAT_LE_POWER_CLASS_1 0x0000000000008000 /*!< LE Power Class 1 supported */ +#define HCI_LE_SUP_FEAT_MIN_NUN_USED_CHAN 0x0000000000010000 /*!< Minimum Number of Used Channels Procedure supported */ +/* Version 5.1 */ +#define HCI_LE_SUP_FEAT_CONN_CTE_REQ 0x0000000000020000 /*!< Connection CTE Request supported */ +#define HCI_LE_SUP_FEAT_CONN_CTE_RSP 0x0000000000040000 /*!< Connection CTE Response supported */ +#define HCI_LE_SUP_FEAT_CONNLESS_CTE_TRANS 0x0000000000080000 /*!< Connectionless CTE Transmitter supported */ +#define HCI_LE_SUP_FEAT_CONNLESS_CTE_RECV 0x0000000000100000 /*!< Connectionless CTE Receiver supported */ +#define HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOD 0x0000000000200000 /*!< Anetenna Switching during CTE Transmission (AoD) supported */ +#define HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOA 0x0000000000400000 /*!< Anetenna Switching during CTE Reception (AoA) supported */ +#define HCI_LE_SUP_FEAT_RECV_CTE 0x0000000000800000 /*!< Receive Constant Tone Extension supported */ +#define HCI_LE_SUP_FEAT_PAST_SENDER 0x0000000001000000 /*!< Periodic Advertising Sync Transfer Sender supported */ +#define HCI_LE_SUP_FEAT_PAST_RECIPIENT 0x0000000002000000 /*!< Periodic Advertising Sync Transfer Recipient supported */ +#define HCI_LE_SUP_FEAT_SCA_UPDATE 0x0000000004000000 /*!< Sleep Clock Accuracy Update supported */ +#define HCI_LE_SUP_FEAT_REMOTE_PUB_KEY_VALIDATION 0x0000000008000000 /*!< Remote Public Key Validation supported */ +/* Version Milan */ +#define HCI_LE_SUP_FEAT_CIS_MASTER 0x0000000010000000 /*!< Connected Isochronous Master Role supported */ +#define HCI_LE_SUP_FEAT_CIS_SLAVE 0x0000000020000000 /*!< Connected Isochronous Slave Role supported */ +#define HCI_LE_SUP_FEAT_ISO_BROADCASTER 0x0000000040000000 /*!< Isochronous Broadcaster Role supported */ +#define HCI_LE_SUP_FEAT_ISO_SYNC_RECEIVER 0x0000000080000000 /*!< Isochronous Synchronized Receiver Role supported */ +#define HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT 0x0000000100000000 /*!< Host support for ISO Channels */ +#define HCI_LE_SUP_FEAT_POWER_CONTROL_REQUEST 0x0000000200000000 /*!< Power control requests supported */ +#define HCI_LE_SUP_FEAT_POWER_CHANGE_IND 0x0000000400000000 /*!< Power control power change indication supported */ +#define HCI_LE_SUP_FEAT_PATH_LOSS_MONITOR 0x0000000800000000 /*!< Path loss monitoring supported */ +/**@}*/ + +/** \name LE feature bit positon in FeatureSet stored in the Controller +* +*/ +/**@{*/ +#define HCI_LE_FEAT_BIT_ISO_HOST_SUPPORT 32 /*!< Host support for ISO Channels */ /**@}*/ /** \name Advertising command parameters * */ /**@{*/ -#define HCI_ADV_MIN_INTERVAL 0x0020 /*!< \brief Minimum advertising interval */ -#define HCI_ADV_MAX_INTERVAL 0x4000 /*!< \brief Maximum advertising interval */ -#define HCI_ADV_DIRECTED_MAX_DURATION 0x0500 /*!< \brief Maximum high duty cycle connectable directed advertising duration */ -#define HCI_ADV_TYPE_CONN_UNDIRECT 0x00 /*!< \brief Connectable undirected advertising */ -#define HCI_ADV_TYPE_CONN_DIRECT 0x01 /*!< \brief Connectable directed high duty cycle advertising */ -#define HCI_ADV_TYPE_DISC_UNDIRECT 0x02 /*!< \brief Discoverable undirected advertising */ -#define HCI_ADV_TYPE_NONCONN_UNDIRECT 0x03 /*!< \brief Nonconnectable undirected advertising */ -#define HCI_ADV_TYPE_CONN_DIRECT_LO_DUTY 0x04 /*!< \brief Connectable directed low duty cycle advertising */ -#define HCI_ADV_CHAN_37 0x01 /*!< \brief Advertising channel 37 */ -#define HCI_ADV_CHAN_38 0x02 /*!< \brief Advertising channel 38 */ -#define HCI_ADV_CHAN_39 0x04 /*!< \brief Advertising channel 39 */ -#define HCI_ADV_FILT_NONE 0x00 /*!< \brief No scan request or connection filtering */ -#define HCI_ADV_FILT_SCAN 0x01 /*!< \brief White list filters scan requests */ -#define HCI_ADV_FILT_CONN 0x02 /*!< \brief White list filters connections */ -#define HCI_ADV_FILT_ALL 0x03 /*!< \brief White list filters scan req. and conn. */ +#define HCI_ADV_MIN_INTERVAL 0x0020 /*!< Minimum advertising interval */ +#define HCI_ADV_MAX_INTERVAL 0x4000 /*!< Maximum advertising interval */ +#define HCI_ADV_DIRECTED_MAX_DURATION 0x0500 /*!< Maximum high duty cycle connectable directed advertising duration */ +#define HCI_ADV_TYPE_CONN_UNDIRECT 0x00 /*!< Connectable undirected advertising */ +#define HCI_ADV_TYPE_CONN_DIRECT 0x01 /*!< Connectable directed high duty cycle advertising */ +#define HCI_ADV_TYPE_DISC_UNDIRECT 0x02 /*!< Discoverable undirected advertising */ +#define HCI_ADV_TYPE_NONCONN_UNDIRECT 0x03 /*!< Nonconnectable undirected advertising */ +#define HCI_ADV_TYPE_CONN_DIRECT_LO_DUTY 0x04 /*!< Connectable directed low duty cycle advertising */ +#define HCI_ADV_CHAN_37 0x01 /*!< Advertising channel 37 */ +#define HCI_ADV_CHAN_38 0x02 /*!< Advertising channel 38 */ +#define HCI_ADV_CHAN_39 0x04 /*!< Advertising channel 39 */ +#define HCI_ADV_FILT_NONE 0x00 /*!< No scan request or connection filtering */ +#define HCI_ADV_FILT_SCAN 0x01 /*!< White list filters scan requests */ +#define HCI_ADV_FILT_CONN 0x02 /*!< White list filters connections */ +#define HCI_ADV_FILT_ALL 0x03 /*!< White list filters scan req. and conn. */ /**@}*/ /** \name Scan command parameters * */ /**@{*/ -#define HCI_SCAN_TYPE_PASSIVE 0 /*!< \brief Passive scan */ -#define HCI_SCAN_TYPE_ACTIVE 1 /*!< \brief Active scan */ -#define HCI_SCAN_INTERVAL_MIN 0x0004 /*!< \brief Minimum scan interval */ -#define HCI_SCAN_INTERVAL_MAX 0x4000 /*!< \brief Maximum scan interval */ -#define HCI_SCAN_INTERVAL_DEFAULT 0x0010 /*!< \brief Default scan interval */ -#define HCI_SCAN_WINDOW_MIN 0x0004 /*!< \brief Minimum scan window */ -#define HCI_SCAN_WINDOW_MAX 0x4000 /*!< \brief Maximum scan window */ -#define HCI_SCAN_WINDOW_DEFAULT 0x0010 /*!< \brief Default scan window */ +#define HCI_SCAN_TYPE_PASSIVE 0 /*!< Passive scan */ +#define HCI_SCAN_TYPE_ACTIVE 1 /*!< Active scan */ +#define HCI_SCAN_INTERVAL_MIN 0x0004 /*!< Minimum scan interval */ +#define HCI_SCAN_INTERVAL_MAX 0x4000 /*!< Maximum scan interval */ +#define HCI_SCAN_INTERVAL_DEFAULT 0x0010 /*!< Default scan interval */ +#define HCI_SCAN_WINDOW_MIN 0x0004 /*!< Minimum scan window */ +#define HCI_SCAN_WINDOW_MAX 0x4000 /*!< Maximum scan window */ +#define HCI_SCAN_WINDOW_DEFAULT 0x0010 /*!< Default scan window */ /**@}*/ /** \name Connection command parameters * */ /**@{*/ -#define HCI_CONN_INTERVAL_MIN 0x0006 /*!< \brief Minimum connection interval */ -#define HCI_CONN_INTERVAL_MAX 0x0C80 /*!< \brief Maximum connection interval */ -#define HCI_CONN_LATENCY_MAX 0x01F3 /*!< \brief Maximum connection latency */ -#define HCI_SUP_TIMEOUT_MIN 0x000A /*!< \brief Minimum supervision timeout */ -#define HCI_SUP_TIMEOUT_MAX 0x0C80 /*!< \brief Maximum supervision timeout */ +#define HCI_CONN_INTERVAL_MIN 0x0006 /*!< Minimum connection interval */ +#define HCI_CONN_INTERVAL_MAX 0x0C80 /*!< Maximum connection interval */ +#define HCI_CONN_LATENCY_MAX 0x01F3 /*!< Maximum connection latency */ +#define HCI_SUP_TIMEOUT_MIN 0x000A /*!< Minimum supervision timeout */ +#define HCI_SUP_TIMEOUT_MAX 0x0C80 /*!< Maximum supervision timeout */ /**@}*/ /** \name Connection event parameters * */ /**@{*/ -#define HCI_ROLE_MASTER 0 /*!< \brief Role is master */ -#define HCI_ROLE_SLAVE 1 /*!< \brief Role is slave */ -#define HCI_CLOCK_500PPM 0x00 /*!< \brief 500 ppm clock accuracy */ -#define HCI_CLOCK_250PPM 0x01 /*!< \brief 250 ppm clock accuracy */ -#define HCI_CLOCK_150PPM 0x02 /*!< \brief 150 ppm clock accuracy */ -#define HCI_CLOCK_100PPM 0x03 /*!< \brief 100 ppm clock accuracy */ -#define HCI_CLOCK_75PPM 0x04 /*!< \brief 75 ppm clock accuracy */ -#define HCI_CLOCK_50PPM 0x05 /*!< \brief 50 ppm clock accuracy */ -#define HCI_CLOCK_30PPM 0x06 /*!< \brief 30 ppm clock accuracy */ -#define HCI_CLOCK_20PPM 0x07 /*!< \brief 20 ppm clock accuracy */ +#define HCI_ROLE_MASTER 0 /*!< Role is master */ +#define HCI_ROLE_SLAVE 1 /*!< Role is slave */ +#define HCI_CLOCK_500PPM 0x00 /*!< 500 ppm clock accuracy */ +#define HCI_CLOCK_250PPM 0x01 /*!< 250 ppm clock accuracy */ +#define HCI_CLOCK_150PPM 0x02 /*!< 150 ppm clock accuracy */ +#define HCI_CLOCK_100PPM 0x03 /*!< 100 ppm clock accuracy */ +#define HCI_CLOCK_75PPM 0x04 /*!< 75 ppm clock accuracy */ +#define HCI_CLOCK_50PPM 0x05 /*!< 50 ppm clock accuracy */ +#define HCI_CLOCK_30PPM 0x06 /*!< 30 ppm clock accuracy */ +#define HCI_CLOCK_20PPM 0x07 /*!< 20 ppm clock accuracy */ /**@}*/ /** \name Advertising report event parameters * */ /**@{*/ -#define HCI_ADV_CONN_UNDIRECT 0x00 /*!< \brief Connectable undirected advertising */ -#define HCI_ADV_CONN_DIRECT 0x01 /*!< \brief Connectable directed advertising */ -#define HCI_ADV_DISC_UNDIRECT 0x02 /*!< \brief Discoverable undirected advertising */ -#define HCI_ADV_NONCONN_UNDIRECT 0x03 /*!< \brief Non-connectable undirected advertising */ -#define HCI_ADV_SCAN_RESPONSE 0x04 /*!< \brief Scan response */ +#define HCI_ADV_CONN_UNDIRECT 0x00 /*!< Connectable undirected advertising */ +#define HCI_ADV_CONN_DIRECT 0x01 /*!< Connectable directed advertising */ +#define HCI_ADV_DISC_UNDIRECT 0x02 /*!< Discoverable undirected advertising */ +#define HCI_ADV_NONCONN_UNDIRECT 0x03 /*!< Non-connectable undirected advertising */ +#define HCI_ADV_SCAN_RESPONSE 0x04 /*!< Scan response */ /**@}*/ /** \name Extended advertising data operations * */ /**@{*/ -#define HCI_ADV_DATA_OP_FRAG_INTER 0x00 /*!< \brief Intermediate fragment */ -#define HCI_ADV_DATA_OP_FRAG_FIRST 0x01 /*!< \brief First fragment */ -#define HCI_ADV_DATA_OP_FRAG_LAST 0x02 /*!< \brief Last fragment */ -#define HCI_ADV_DATA_OP_COMP_FRAG 0x03 /*!< \brief Complete extended advertising data */ -#define HCI_ADV_DATA_OP_UNCHANGED_DATA 0x04 /*!< \brief Unchanged data (just update Advertising DID) */ +#define HCI_ADV_DATA_OP_FRAG_INTER 0x00 /*!< Intermediate fragment */ +#define HCI_ADV_DATA_OP_FRAG_FIRST 0x01 /*!< First fragment */ +#define HCI_ADV_DATA_OP_FRAG_LAST 0x02 /*!< Last fragment */ +#define HCI_ADV_DATA_OP_COMP_FRAG 0x03 /*!< Complete extended advertising data */ +#define HCI_ADV_DATA_OP_UNCHANGED_DATA 0x04 /*!< Unchanged data (just update Advertising DID) */ /**@}*/ /** \name Advertising data fragment preference * */ /**@{*/ -#define HCI_ADV_DATA_FRAG_PREF_FRAG 0x00 /*!< \brief Controller may fragment all Host advertising data */ -#define HCI_ADV_DATA_FRAG_PREF_NO_FRAG 0x01 /*!< \brief Controller should not fragment nor minimize fragmentation of Host advertising data */ +#define HCI_ADV_DATA_FRAG_PREF_FRAG 0x00 /*!< Controller may fragment all Host advertising data */ +#define HCI_ADV_DATA_FRAG_PREF_NO_FRAG 0x01 /*!< Controller should not fragment nor minimize fragmentation of Host advertising data */ /**@}*/ /** \name Number of advertising sets * */ /**@{*/ -#define HCI_ADV_NUM_SETS_ALL_DISABLE 0x00 /*!< \brief Disable all advertising sets */ +#define HCI_ADV_NUM_SETS_ALL_DISABLE 0x00 /*!< Disable all advertising sets */ /**@}*/ /** \name Maximum number of scanning or initiating PHYs * */ /**@{*/ -#define HCI_MAX_NUM_PHYS 3 /*!< \brief Maximum number of scanning or initiating PHYs */ +#define HCI_MAX_NUM_PHYS 3 /*!< Maximum number of scanning or initiating PHYs */ /**@}*/ /** \name Advertising PHY values * */ /**@{*/ -#define HCI_ADV_PHY_LE_1M 0x01 /*!< \brief LE 1M PHY */ -#define HCI_ADV_PHY_LE_2M 0x02 /*!< \brief LE 2M PHY */ -#define HCI_ADV_PHY_LE_CODED 0x03 /*!< \brief LE Coded PHY */ +#define HCI_ADV_PHY_LE_1M 0x01 /*!< LE 1M PHY */ +#define HCI_ADV_PHY_LE_2M 0x02 /*!< LE 2M PHY */ +#define HCI_ADV_PHY_LE_CODED 0x03 /*!< LE Coded PHY */ /**@}*/ /** \name Scanner PHY value bits * */ /**@{*/ -#define HCI_SCAN_PHY_LE_1M_BIT (1<<0) /*!< \brief LE 1M PHY */ -#define HCI_SCAN_PHY_LE_2M_BIT (1<<1) /*!< \brief LE 2M PHY */ -#define HCI_SCAN_PHY_LE_CODED_BIT (1<<2) /*!< \brief LE Coded PHY */ +#define HCI_SCAN_PHY_LE_1M_BIT (1<<0) /*!< LE 1M PHY */ +#define HCI_SCAN_PHY_LE_2M_BIT (1<<1) /*!< LE 2M PHY */ +#define HCI_SCAN_PHY_LE_CODED_BIT (1<<2) /*!< LE Coded PHY */ /**@}*/ /** \name Initiator PHY value bits * */ /**@{*/ -#define HCI_INIT_PHY_LE_1M_BIT (1<<0) /*!< \brief LE 1M PHY */ -#define HCI_INIT_PHY_LE_2M_BIT (1<<1) /*!< \brief LE 2M PHY */ -#define HCI_INIT_PHY_LE_CODED_BIT (1<<2) /*!< \brief LE Coded PHY */ +#define HCI_INIT_PHY_LE_1M_BIT (1<<0) /*!< LE 1M PHY */ +#define HCI_INIT_PHY_LE_2M_BIT (1<<1) /*!< LE 2M PHY */ +#define HCI_INIT_PHY_LE_CODED_BIT (1<<2) /*!< LE Coded PHY */ +/**@}*/ + +/** \name Transmitter PHY value bits +* +*/ +/**@{*/ +#define HCI_TRANS_PHY_LE_1M_BIT (1<<0) /*!< LE 1M PHY */ +#define HCI_TRANS_PHY_LE_2M_BIT (1<<1) /*!< LE 2M PHY */ +#define HCI_TRABS_PHY_LE_CODED_BIT (1<<2) /*!< LE Coded PHY */ /**@}*/ /** \name Advertising event properties type bits * */ /**@{*/ -#define HCI_ADV_PROP_CONN_ADV_BIT (1<<0) /*!< \brief Connectable advertising bit */ -#define HCI_ADV_PROP_SCAN_ADV_BIT (1<<1) /*!< \brief Scannable advertising bit */ -#define HCI_ADV_PROP_DIRECT_ADV_BIT (1<<2) /*!< \brief Directed advertising bit */ -#define HCI_ADV_PROP_CONN_DIRECT_ADV_BIT (1<<3) /*!< \brief High duty cycle connectable directed advertising bit */ -#define HCI_ADV_PROP_USE_LEG_PDU_BIT (1<<4) /*!< \brief Use legacy advertising PDUs bit */ -#define HCI_ADV_PROP_OMIT_ADV_ADDR_BIT (1<<5) /*!< \brief Omit advertiser's address from all PDUs (anonymous advertising) bit */ -#define HCI_ADV_PROP_INC_TX_PWR_BIT (1<<6) /*!< \brief Include TxPower in extended header of advertising PDU bit */ +#define HCI_ADV_PROP_CONN_ADV_BIT (1<<0) /*!< Connectable advertising bit */ +#define HCI_ADV_PROP_SCAN_ADV_BIT (1<<1) /*!< Scannable advertising bit */ +#define HCI_ADV_PROP_DIRECT_ADV_BIT (1<<2) /*!< Directed advertising bit */ +#define HCI_ADV_PROP_CONN_DIRECT_ADV_BIT (1<<3) /*!< High duty cycle connectable directed advertising bit */ +#define HCI_ADV_PROP_USE_LEG_PDU_BIT (1<<4) /*!< Use legacy advertising PDUs bit */ +#define HCI_ADV_PROP_OMIT_ADV_ADDR_BIT (1<<5) /*!< Omit advertiser's address from all PDUs (anonymous advertising) bit */ +#define HCI_ADV_PROP_INC_TX_PWR_BIT (1<<6) /*!< Include TxPower in extended header of advertising PDU bit */ /**@}*/ /** \name Advertising event properties for legacy PDUs * */ /**@{*/ -#define HCI_ADV_PROP_LEG_CONN_UNDIRECT 0x13 /*!< \brief Connectable and scannable undirected advertising (00010011b) */ -#define HCI_ADV_PROP_LEG_CONN_DIRECT 0x1D /*!< \brief Connectable directed high duty cycle advertising (00011101b) */ -#define HCI_ADV_PROP_LEG_SCAN_UNDIRECT 0x12 /*!< \brief Scannable undirected advertising (00010010b) */ -#define HCI_ADV_PROP_LEG_NONCONN_UNDIRECT 0x10 /*!< \brief Non-connectable and non-scannable undirected advertising (00010000b) */ -#define HCI_ADV_PROP_LEG_CONN_DIRECT_LO_DUTY 0x15 /*!< \brief Connectable directed low duty cycle advertising (00010101b) */ +#define HCI_ADV_PROP_LEG_CONN_UNDIRECT 0x13 /*!< Connectable and scannable undirected advertising (00010011b) */ +#define HCI_ADV_PROP_LEG_CONN_DIRECT 0x1D /*!< Connectable directed high duty cycle advertising (00011101b) */ +#define HCI_ADV_PROP_LEG_SCAN_UNDIRECT 0x12 /*!< Scannable undirected advertising (00010010b) */ +#define HCI_ADV_PROP_LEG_NONCONN_UNDIRECT 0x10 /*!< Non-connectable and non-scannable undirected advertising (00010000b) */ +#define HCI_ADV_PROP_LEG_CONN_DIRECT_LO_DUTY 0x15 /*!< Connectable directed low duty cycle advertising (00010101b) */ /**@}*/ /** \name Extended advertising report event type bits * */ /**@{*/ -#define HCI_ADV_RPT_CONN_ADV_BIT (1<<0) /*!< \brief Connectable advertising event bit */ -#define HCI_ADV_RPT_SCAN_ADV_BIT (1<<1) /*!< \brief Scannable advertising event bit */ -#define HCI_ADV_RPT_DIRECT_ADV_BIT (1<<2) /*!< \brief Directed advertising event bit */ -#define HCI_ADV_RPT_SCAN_RSP_BIT (1<<3) /*!< \brief Scan response event bit */ -#define HCI_ADV_RPT_LEG_ADV_BIT (1<<4) /*!< \brief Legacy advertising PDU event bit */ -#define HCI_ADV_RPT_DATA_STATUS_BITS (3<<5) /*!< \brief Data status bits */ +#define HCI_ADV_RPT_CONN_ADV_BIT (1<<0) /*!< Connectable advertising event bit */ +#define HCI_ADV_RPT_SCAN_ADV_BIT (1<<1) /*!< Scannable advertising event bit */ +#define HCI_ADV_RPT_DIRECT_ADV_BIT (1<<2) /*!< Directed advertising event bit */ +#define HCI_ADV_RPT_SCAN_RSP_BIT (1<<3) /*!< Scan response event bit */ +#define HCI_ADV_RPT_LEG_ADV_BIT (1<<4) /*!< Legacy advertising PDU event bit */ +#define HCI_ADV_RPT_DATA_STATUS_BITS (3<<5) /*!< Data status bits */ /**@}*/ /** \name Advertising report event types for legacy PDUs * */ /**@{*/ -#define HCI_ADV_RPT_LEG_CONN_UNDIRECT 0x13 /*!< \brief Connectable and scannable undirected advertising (0010011b) */ -#define HCI_ADV_RPT_LEG_CONN_DIRECT 0x15 /*!< \brief Connectable directed advertising (0010101b) */ -#define HCI_ADV_RPT_LEG_SCAN_UNDIRECT 0x12 /*!< \brief Scannable undirected advertising (0010010b) */ -#define HCI_ADV_RPT_LEG_NONCONN_UNDIRECT 0x10 /*!< \brief Non-connectable and non-scannable undirected advertising (0010000b) */ -#define HCI_ADV_RPT_LEG_CONN_UNDIRECT_SCAN_RSP 0x1B /*!< \brief Scan response to connectable and scannable undirected advertising (0011011b) */ -#define HCI_ADV_RPT_LEG_SCAN_UNDIRECT_SCAN_RSP 0x1A /*!< \brief Scan response to scannable undirected advertising (0011010b) */ +#define HCI_ADV_RPT_LEG_CONN_UNDIRECT 0x13 /*!< Connectable and scannable undirected advertising (0010011b) */ +#define HCI_ADV_RPT_LEG_CONN_DIRECT 0x15 /*!< Connectable directed advertising (0010101b) */ +#define HCI_ADV_RPT_LEG_SCAN_UNDIRECT 0x12 /*!< Scannable undirected advertising (0010010b) */ +#define HCI_ADV_RPT_LEG_NONCONN_UNDIRECT 0x10 /*!< Non-connectable and non-scannable undirected advertising (0010000b) */ +#define HCI_ADV_RPT_LEG_CONN_UNDIRECT_SCAN_RSP 0x1B /*!< Scan response to connectable and scannable undirected advertising (0011011b) */ +#define HCI_ADV_RPT_LEG_SCAN_UNDIRECT_SCAN_RSP 0x1A /*!< Scan response to scannable undirected advertising (0011010b) */ /**@}*/ /** \name Advertising report data status * */ /**@{*/ -#define HCI_ADV_RPT_DATA_CMPL 0x00 /*!< \brief Data complete */ -#define HCI_ADV_RPT_DATA_INCMPL_MORE 0x01 /*!< \brief Data incomplete, more date to come */ -#define HCI_ADV_RPT_DATA_INCMPL_TRUNC 0x02 /*!< \brief Data incomplete, data truncated, no more date to come */ +#define HCI_ADV_RPT_DATA_CMPL 0x00 /*!< Data complete */ +#define HCI_ADV_RPT_DATA_INCMPL_MORE 0x01 /*!< Data incomplete, more date to come */ +#define HCI_ADV_RPT_DATA_INCMPL_TRUNC 0x02 /*!< Data incomplete, data truncated, no more date to come */ /**@}*/ /** \name Extended advertising report event primary PHY values * */ /**@{*/ -#define HCI_ADV_RPT_PHY_PRIM_LE_1M 0x01 /*!< \brief Advertiser PHY is LE 1M */ -#define HCI_ADV_RPT_PHY_PRIM_LE_CODED 0x03 /*!< \brief Advertiser PHY is LE Coded */ +#define HCI_ADV_RPT_PHY_PRIM_LE_1M 0x01 /*!< Advertiser PHY is LE 1M */ +#define HCI_ADV_RPT_PHY_PRIM_LE_CODED 0x03 /*!< Advertiser PHY is LE Coded */ /**@}*/ /** \name Extended advertising report event seconday PHY values * */ /**@{*/ -#define HCI_ADV_RPT_PHY_SEC_NONE 0x00 /*!< \brief No packets on seconday advertising channel */ -#define HCI_ADV_RPT_PHY_SEC_LE_1M 0x01 /*!< \brief Advertiser PHY is LE 1M */ -#define HCI_ADV_RPT_PHY_SEC_LE_2M 0x02 /*!< \brief Advertiser PHY is LE 2M */ -#define HCI_ADV_RPT_PHY_SEC_LE_CODED 0x03 /*!< \brief Advertiser PHY is LE Coded */ +#define HCI_ADV_RPT_PHY_SEC_NONE 0x00 /*!< No packets on seconday advertising channel */ +#define HCI_ADV_RPT_PHY_SEC_LE_1M 0x01 /*!< Advertiser PHY is LE 1M */ +#define HCI_ADV_RPT_PHY_SEC_LE_2M 0x02 /*!< Advertiser PHY is LE 2M */ +#define HCI_ADV_RPT_PHY_SEC_LE_CODED 0x03 /*!< Advertiser PHY is LE Coded */ /**@}*/ /** \name Channel selection algorithm used * */ /**@{*/ -#define HCI_CH_SEL_ALGO_1 0x00 /*!< \brief LE channel selection algorithm #1 used */ -#define HCI_CH_SEL_ALGO_2 0x01 /*!< \brief LE channel selection algorithm #2 used */ +#define HCI_CH_SEL_ALGO_1 0x00 /*!< LE channel selection algorithm #1 used */ +#define HCI_CH_SEL_ALGO_2 0x01 /*!< LE channel selection algorithm #2 used */ /**@}*/ /** \name KeyType parameters * */ /**@{*/ -#define HCI_PRIVATE_KEY_GENERATED 0x00 /*!< \brief Use generated private key */ -#define HCI_PRIVATE_KEY_DEBUG 0x01 /*!< \brief Use debug private key */ +#define HCI_PRIVATE_KEY_GENERATED 0x00 /*!< Use generated private key */ +#define HCI_PRIVATE_KEY_DEBUG 0x01 /*!< Use debug private key */ /**@{*/ /**@{*/ @@ -1167,130 +1283,130 @@ extern "C" { * */ /**@{*/ -#define HCI_MIN_NUM_OF_USED_CHAN 8 /*!< \brief Minimum number of used channels */ +#define HCI_MIN_NUM_OF_USED_CHAN 8 /*!< Minimum number of used channels */ /**@}*/ /** \name Synchronization timeout for the periodic advertising * */ /**@{*/ -#define HCI_SYNC_MIN_TIMEOUT 0x000A /*!< \brief Minimum synchronization timeout */ -#define HCI_SYNC_MAX_TIMEOUT 0x4000 /*!< \brief Maximum synchronization timeout */ +#define HCI_SYNC_MIN_TIMEOUT 0x000A /*!< Minimum synchronization timeout */ +#define HCI_SYNC_MAX_TIMEOUT 0x4000 /*!< Maximum synchronization timeout */ /**@}*/ /** \name Maximum synchronization skip * */ /**@{*/ -#define HCI_SYNC_MAX_SKIP 0x01F3 /*!< \brief Maximum synchronization skip */ +#define HCI_SYNC_MAX_SKIP 0x01F3 /*!< Maximum synchronization skip */ /**@}*/ /** \name Maximum synchronization handle * */ /**@{*/ -#define HCI_SYNC_MAX_HANDLE 0x0EFF /*!< \brief Maximum synchronization handle */ +#define HCI_SYNC_MAX_HANDLE 0x0EFF /*!< Maximum synchronization handle */ /**@}*/ /** \name Periodic sync transfer receive mode * */ /**@{*/ -#define HCI_SYNC_TRSF_MODE_OFF 0x00 /*!< \brief Periodic sync transfer receive is disabled */ -#define HCI_SYNC_TRSF_MODE_REP_DISABLED 0x01, /*!< \brief Periodic sync transfer receive is enabled, report event is disabled */ -#define HCI_SYNC_TRSF_MODE_REP_ENABLED 0x02, /*!< \brief Periodic sync transfer receive is enabled, report event is enabled */ +#define HCI_SYNC_TRSF_MODE_OFF 0x00 /*!< Periodic sync transfer receive is disabled */ +#define HCI_SYNC_TRSF_MODE_REP_DISABLED 0x01, /*!< Periodic sync transfer receive is enabled, report event is disabled */ +#define HCI_SYNC_TRSF_MODE_REP_ENABLED 0x02, /*!< Periodic sync transfer receive is enabled, report event is enabled */ /**@}*/ /** \name Periodic advertising create sync options bits * */ /**@{*/ -#define HCI_OPTIONS_FILT_POLICY_BIT (1<<0) /*!< \brief filter policy bit */ -#define HCI_OPTIONS_INIT_RPT_ENABLE_BIT (1<<1) /*!< \brief initial periodic advertisement reporting bit */ +#define HCI_OPTIONS_FILT_POLICY_BIT (1<<0) /*!< filter policy bit */ +#define HCI_OPTIONS_INIT_RPT_ENABLE_BIT (1<<1) /*!< initial periodic advertisement reporting bit */ /**@}*/ /** \name Misc command parameters * */ /**@{*/ -#define HCI_READ_TX_PWR_CURRENT 0 /*!< \brief Read current tx power */ -#define HCI_READ_TX_PWR_MAX 1 /*!< \brief Read maximum tx power */ -#define HCI_TX_PWR_MIN -30 /*!< \brief Minimum tx power dBm */ -#define HCI_TX_PWR_MAX 20 /*!< \brief Maximum tx power dBm */ -#define HCI_TX_PWR_NO_PREFERENCE 127 /*!< \brief Tx power no preference */ -#define HCI_VERSION 6 /*!< \brief HCI specification version */ -#define HCI_RSSI_MIN -127 /*!< \brief Minimum RSSI dBm */ -#define HCI_RSSI_MAX 20 /*!< \brief Maximum RSSI dBm */ -#define HCI_ADDR_TYPE_PUBLIC 0 /*!< \brief Public device address */ -#define HCI_ADDR_TYPE_RANDOM 1 /*!< \brief Random device address */ -#define HCI_ADDR_TYPE_PUBLIC_IDENTITY 2 /*!< \brief Public identity address */ -#define HCI_ADDR_TYPE_RANDOM_IDENTITY 3 /*!< \brief Random identity address */ -#define HCI_ADDR_TYPE_ANONYMOUS 0xFF /*!< \brief Anonymous device address */ -#define HCI_FILT_NONE 0 /*!< \brief Accept all advertising packets */ -#define HCI_FILT_WHITE_LIST 1 /*!< \brief Accept from While List only */ -#define HCI_FILT_RES_INIT 2 /*!< \brief Accept directed advertisements with RPAs */ -#define HCI_FILT_WHITE_LIST_RES_INIT 3 /*!< \brief Accept from White List or directed advertisements with RPAs */ -#define HCI_FILT_PER_ADV_PARAM 0 /*!< \brief Listen to advertiser specified by create sync command parameters */ -#define HCI_FILT_PER_ADV_LIST 1 /*!< \brief Listen to advertiser from Periodic Advertiser List only */ -#define HCI_ROLE_MASTER 0 /*!< \brief Role is master */ -#define HCI_ROLE_SLAVE 1 /*!< \brief Role is slave */ -#define HCI_PRIV_MODE_NETWORK 0x00 /*!< \brief Network privacy mode (default) */ -#define HCI_PRIV_MODE_DEVICE 0x01 /*!< \brief Device privacy mode */ +#define HCI_READ_TX_PWR_CURRENT 0 /*!< Read current tx power */ +#define HCI_READ_TX_PWR_MAX 1 /*!< Read maximum tx power */ +#define HCI_TX_PWR_MIN -30 /*!< Minimum tx power dBm */ +#define HCI_TX_PWR_MAX 20 /*!< Maximum tx power dBm */ +#define HCI_TX_PWR_NO_PREFERENCE 127 /*!< Tx power no preference */ +#define HCI_VERSION 6 /*!< HCI specification version */ +#define HCI_RSSI_MIN -127 /*!< Minimum RSSI dBm */ +#define HCI_RSSI_MAX 20 /*!< Maximum RSSI dBm */ +#define HCI_ADDR_TYPE_PUBLIC 0 /*!< Public device address */ +#define HCI_ADDR_TYPE_RANDOM 1 /*!< Random device address */ +#define HCI_ADDR_TYPE_PUBLIC_IDENTITY 2 /*!< Public identity address */ +#define HCI_ADDR_TYPE_RANDOM_IDENTITY 3 /*!< Random identity address */ +#define HCI_ADDR_TYPE_ANONYMOUS 0xFF /*!< Anonymous device address */ +#define HCI_FILT_NONE 0 /*!< Accept all advertising packets */ +#define HCI_FILT_WHITE_LIST 1 /*!< Accept from While List only */ +#define HCI_FILT_RES_INIT 2 /*!< Accept directed advertisements with RPAs */ +#define HCI_FILT_WHITE_LIST_RES_INIT 3 /*!< Accept from White List or directed advertisements with RPAs */ +#define HCI_FILT_PER_ADV_PARAM 0 /*!< Listen to advertiser specified by create sync command parameters */ +#define HCI_FILT_PER_ADV_LIST 1 /*!< Listen to advertiser from Periodic Advertiser List only */ +#define HCI_ROLE_MASTER 0 /*!< Role is master */ +#define HCI_ROLE_SLAVE 1 /*!< Role is slave */ +#define HCI_PRIV_MODE_NETWORK 0x00 /*!< Network privacy mode (default) */ +#define HCI_PRIV_MODE_DEVICE 0x01 /*!< Device privacy mode */ /**@}*/ /** \name PHY types * */ /**@{*/ -#define HCI_PHY_NONE 0x00 /*!< \brief No selected PHY */ -#define HCI_PHY_LE_1M_BIT (1<<0) /*!< \brief LE 1M PHY */ -#define HCI_PHY_LE_2M_BIT (1<<1) /*!< \brief LE 2M PHY */ -#define HCI_PHY_LE_CODED_BIT (1<<2) /*!< \brief LE Coded PHY */ +#define HCI_PHY_NONE 0x00 /*!< No selected PHY */ +#define HCI_PHY_LE_1M_BIT (1<<0) /*!< LE 1M PHY */ +#define HCI_PHY_LE_2M_BIT (1<<1) /*!< LE 2M PHY */ +#define HCI_PHY_LE_CODED_BIT (1<<2) /*!< LE Coded PHY */ /**@}*/ /** \name All PHYs preference * */ /**@{*/ -#define HCI_ALL_PHY_ALL_PREFERENCES 0x00 /*!< \brief All PHY preferences */ -#define HCI_ALL_PHY_TX_PREFERENCE_BIT (1<<0) /*!< \brief Tx PHY preference */ -#define HCI_ALL_PHY_RX_PREFERENCE_BIT (1<<1) /*!< \brief Rx PHY preference */ +#define HCI_ALL_PHY_ALL_PREFERENCES 0x00 /*!< All PHY preferences */ +#define HCI_ALL_PHY_TX_PREFERENCE_BIT (1<<0) /*!< Tx PHY preference */ +#define HCI_ALL_PHY_RX_PREFERENCE_BIT (1<<1) /*!< Rx PHY preference */ /**@}*/ /** \name PHY options * */ /**@{*/ -#define HCI_PHY_OPTIONS_NONE 0x00 /*!< \brief No preferences */ -#define HCI_PHY_OPTIONS_S2_PREFERRED 0x01 /*!< \brief S=2 coding preferred when transmitting on LE Coded PHY */ -#define HCI_PHY_OPTIONS_S8_PREFERRED 0x02 /*!< \brief S=8 coding preferred when transmitting on LE Coded PHY */ +#define HCI_PHY_OPTIONS_NONE 0x00 /*!< No preferences */ +#define HCI_PHY_OPTIONS_S2_PREFERRED 0x01 /*!< S=2 coding preferred when transmitting on LE Coded PHY */ +#define HCI_PHY_OPTIONS_S8_PREFERRED 0x02 /*!< S=8 coding preferred when transmitting on LE Coded PHY */ /**@}*/ /** \name CTE Slot Durations * */ /**@{*/ -#define HCI_CTE_SLOT_DURATION_NONE 0x00 /*!< \brief No switching and sampling */ -#define HCI_CTE_SLOT_DURATION_1_US 0x01 /*!< \brief Switching and sampling slots are 1 us each */ -#define HCI_CTE_SLOT_DURATION_2_US 0x02 /*!< \brief Switching and sampling slots are 2 us each */ +#define HCI_CTE_SLOT_DURATION_NONE 0x00 /*!< No switching and sampling */ +#define HCI_CTE_SLOT_DURATION_1_US 0x01 /*!< Switching and sampling slots are 1 us each */ +#define HCI_CTE_SLOT_DURATION_2_US 0x02 /*!< Switching and sampling slots are 2 us each */ /**@}*/ /** \name Permitted CTE Type bits * */ /**@{*/ -#define HCI_CTE_TYPE_PERMIT_AOA_RSP_BIT (1<<0) /*!< \brief Allow AoA Constant Tone Extension Response */ -#define HCI_CTE_TYPE_PERMIT_AOD_RSP_1_US_BIT (1<<1) /*!< \brief Allow AoD Constant Tone Extension Response with 1 us slots */ -#define HCI_CTE_TYPE_PERMIT_AOD_RSP_2_US_BIT (1<<2) /*!< \brief Allow AoD Constant Tone Extension Response with 2 us slots */ +#define HCI_CTE_TYPE_PERMIT_AOA_RSP_BIT (1<<0) /*!< Allow AoA Constant Tone Extension Response */ +#define HCI_CTE_TYPE_PERMIT_AOD_RSP_1_US_BIT (1<<1) /*!< Allow AoD Constant Tone Extension Response with 1 us slots */ +#define HCI_CTE_TYPE_PERMIT_AOD_RSP_2_US_BIT (1<<2) /*!< Allow AoD Constant Tone Extension Response with 2 us slots */ /**@}*/ /** \name Requested CTE Types * */ /**@{*/ -#define HCI_CTE_TYPE_REQ_AOA 0x00 /*!< \brief AoA Constant Tone Extension */ -#define HCI_CTE_TYPE_REQ_AOD_1_US 0x01 /*!< \brief AoD Constant Tone Extension with 1 us slots */ -#define HCI_CTE_TYPE_REQ_AOD_2_US 0x02 /*!< \brief AoD Constant Tone Extension with 2 us slots */ +#define HCI_CTE_TYPE_REQ_AOA 0x00 /*!< AoA Constant Tone Extension */ +#define HCI_CTE_TYPE_REQ_AOD_1_US 0x01 /*!< AoD Constant Tone Extension with 1 us slots */ +#define HCI_CTE_TYPE_REQ_AOD_2_US 0x02 /*!< AoD Constant Tone Extension with 2 us slots */ /**@}*/ /** \name Bluetooth core specification versions @@ -1302,65 +1418,252 @@ extern "C" { #define HCI_VER_BT_CORE_SPEC_4_2 0x08 /*!< Bluetooth core specification 4.2 */ #define HCI_VER_BT_CORE_SPEC_5_0 0x09 /*!< Bluetooth core specification 5.0 */ #define HCI_VER_BT_CORE_SPEC_5_1 0x0A /*!< Bluetooth core specification 5.1 */ +#define HCI_VER_BT_CORE_SPEC_5_2 0x0B /*!< Bluetooth core specification 5.2 */ /**@}*/ /** \name Parameter lengths * */ /**@{*/ -#define HCI_EVT_MASK_LEN 8 /*!< \brief Length of event mask byte array */ -#define HCI_EVT_MASK_PAGE_2_LEN 8 /*!< \brief Length of event mask page 2 byte array */ -#define HCI_LE_EVT_MASK_LEN 8 /*!< \brief Length of LE event mask byte array */ -#define HCI_FEAT_LEN 8 /*!< \brief Length of features byte array */ -#define HCI_ADV_DATA_LEN 31 /*!< \brief Length of advertising data */ -#define HCI_SCAN_DATA_LEN 31 /*!< \brief Length of scan response data */ -#define HCI_EXT_ADV_DATA_LEN 251 /*!< \brief Length of extended advertising data */ -#define HCI_EXT_ADV_CONN_DATA_LEN 191 /*!< \brief Length of extended connectable advertising data */ -#define HCI_PER_ADV_DATA_LEN 252 /*!< \brief Length of periodic advertising data */ -#define HCI_EXT_ADV_RPT_DATA_LEN 229 /*!< \brief Length of extended advertising report data */ -#define HCI_PER_ADV_RPT_DATA_LEN 247 /*!< \brief Length of periodic advertising report data */ -#define HCI_CHAN_MAP_LEN 5 /*!< \brief Length of channel map byte array */ -#define HCI_KEY_LEN 16 /*!< \brief Length of encryption key */ -#define HCI_ENCRYPT_DATA_LEN 16 /*!< \brief Length of data used in encryption */ -#define HCI_RAND_LEN 8 /*!< \brief Length of random number */ -#define HCI_LE_STATES_LEN 8 /*!< \brief Length of LE states byte array */ -#define HCI_P256_KEY_LEN 64 /*!< \brief Length of P256 key */ -#define HCI_DH_KEY_LEN 32 /*!< \brief Length of DH Key */ - -#define HCI_EXT_ADV_RPT_DATA_LEN_OFFSET 23 /*!< \brief Length field offset of extended advertising report data */ -#define HCI_PER_ADV_RPT_DATA_LEN_OFFSET 6 /*!< \brief Length field offset of periodic advertising report data */ +#define HCI_EVT_MASK_LEN 8 /*!< Length of event mask byte array */ +#define HCI_EVT_MASK_PAGE_2_LEN 8 /*!< Length of event mask page 2 byte array */ +#define HCI_LE_EVT_MASK_LEN 8 /*!< Length of LE event mask byte array */ +#define HCI_FEAT_LEN 8 /*!< Length of features byte array */ +#define HCI_ADV_DATA_LEN 31 /*!< Length of advertising data */ +#define HCI_SCAN_DATA_LEN 31 /*!< Length of scan response data */ +#define HCI_EXT_ADV_DATA_LEN 251 /*!< Length of extended advertising data */ +#define HCI_EXT_ADV_CONN_DATA_LEN 191 /*!< Length of extended connectable advertising data */ +#define HCI_PER_ADV_DATA_LEN 252 /*!< Length of periodic advertising data */ +#define HCI_EXT_ADV_RPT_DATA_LEN 229 /*!< Length of extended advertising report data */ +#define HCI_PER_ADV_RPT_DATA_LEN 247 /*!< Length of periodic advertising report data */ +#define HCI_CHAN_MAP_LEN 5 /*!< Length of channel map byte array */ +#define HCI_KEY_LEN 16 /*!< Length of encryption key */ +#define HCI_ENCRYPT_DATA_LEN 16 /*!< Length of data used in encryption */ +#define HCI_RAND_LEN 8 /*!< Length of random number */ +#define HCI_LE_STATES_LEN 8 /*!< Length of LE states byte array */ +#define HCI_P256_KEY_LEN 64 /*!< Length of P256 key */ +#define HCI_DH_KEY_LEN 32 /*!< Length of DH Key */ +#define HCI_BC_LEN 16 /*!< Broadcast code length */ + +#define HCI_EXT_ADV_RPT_DATA_LEN_OFFSET 23 /*!< Length field offset of extended advertising report data */ +#define HCI_PER_ADV_RPT_DATA_LEN_OFFSET 6 /*!< Length field offset of periodic advertising report data */ /**@}*/ /** \name Number of Antenna IDs in Switching Pattern * */ /**@{*/ -#define HCI_MIN_NUM_ANTENNA_IDS 2 /*!< \brief Minimum number of Antenna IDs in switching pattern */ -#define HCI_MAX_NUM_ANTENNA_IDS 75 /*!< \brief Maximum number of Antenna IDs in switching pattern */ +#define HCI_MIN_NUM_ANTENNA_IDS 2 /*!< Minimum number of Antenna IDs in switching pattern */ +#define HCI_MAX_NUM_ANTENNA_IDS 75 /*!< Maximum number of Antenna IDs in switching pattern */ /**@}*/ /** \name IQ Report Sample Counts * */ /**@{*/ -#define HCI_IQ_RPT_SAMPLE_CNT_MIN 9 /*!< \brief Minimum number of sample pairs in IQ report */ -#define HCI_IQ_RPT_SAMPLE_CNT_MAX 82 /*!< \brief Maximum number of sample pairs in IQ report */ +#define HCI_IQ_RPT_SAMPLE_CNT_MIN 9 /*!< Minimum number of sample pairs in IQ report */ +#define HCI_IQ_RPT_SAMPLE_CNT_MAX 82 /*!< Maximum number of sample pairs in IQ report */ -#define HCI_CONN_IQ_RPT_SAMPLE_CNT_OFFSET 12 /*!< \brief Sample count field offset of connection IQ report */ +#define HCI_CONN_IQ_RPT_SAMPLE_CNT_OFFSET 12 /*!< Sample count field offset of connection IQ report */ +/**@}*/ + +/** \name CIS Count +* +*/ +/**@{*/ +#define HCI_MAX_CIS_COUNT 0x10 /*!< Maximum count for CIS */ +/**@}*/ + +/** \name BIS Count +* +*/ +/**@{*/ +#define HCI_MAX_BIS_COUNT 0x10 /*!< Maximum count for BIS */ +/**@}*/ + +/** \name CIG IDs +* +*/ +/**@{*/ +#define HCI_MIN_CIG_ID 0x00 /*!< Minimum value for CIG ID. */ +#define HCI_MAX_CIG_ID 0xEF /*!< Maximum value for CIG ID. */ +/**@}*/ + +/** \name CIS IDs +* +*/ +/**@{*/ +#define HCI_MIN_CIS_ID 0x00 /*!< Minimum value for CIS ID. */ +#define HCI_MAX_CIS_ID 0xEF /*!< Maximum value for CIS ID. */ +/**@}*/ + +/** \name Packing Scheme +* +*/ +/**@{*/ +#define HCI_PACKING_SEQUENTIAL 0x00 /*!< Sequential */ +#define HCI_PACKING_INTERLEAVED 0x01 /*!< Interleaved */ +/**@}*/ + +/** \name Framing +* +*/ +/**@{*/ +#define HCI_FRAMING_UNFRAMED 0x00 /*!< Unframed */ +#define HCI_FRAMING_FRAMED 0x01 /*!< Framed */ +/**@}*/ + +/** \name Slave Clock Accuracy +* +*/ +/**@{*/ +#define HCI_MIN_SCA 0x00 /*!< Minimum value for SCA. */ +#define HCI_MAX_SCA 0x07 /*!< Maximum value for SCA. */ + +/** \name SDU Size +* +*/ +/**@{*/ +#define HCI_MIN_SDU_SIZE 0x0000 /*!< Minimum value for SDU size. */ +#define HCI_MAX_SDU_SIZE 0x0FFF /*!< Maximum value for SDU size. */ +/**@}*/ + +/** \name SDU Interval +* +*/ +/**@{*/ +#define HCI_MIN_SDU_INTERV 0x0000FF /*!< Minimum value for SDU interval. */ +#define HCI_MAX_SDU_INTERV 0x0FFFFF /*!< Maximum value for SDU interval. */ +#define HCI_DEFAULT_SDU_INTERV 0x004E20 /*!< Default value for SDU interval. */ +/**@}*/ + +/** \name CIS Transport Latency +* +*/ +/**@{*/ +#define HCI_MIN_CIS_TRANS_LAT 0x0005 /*!< Minimum value for CIS transport latency. */ +#define HCI_MAX_CIS_TRANS_LAT 0x0FA0 /*!< Maximum value for CIS transport latency. */ +#define HCI_DEFAULT_CIS_TRANS_LAT 0x0028 /*!< Default value for CIS transport latency. */ +/**@}*/ + +/** \name CIS Flush Time +* +*/ +/**@{*/ +#define HCI_MIN_CIS_FT 0x01 /*!< Minimum value for CIS flush time. */ +#define HCI_MAX_CIS_FT 0xFF /*!< Maximum value for CIS flush time. */ +/**@}*/ + +/** \name CIS Burst Number +* +*/ +/**@{*/ +#define HCI_MIN_CIS_BN 0x00 /*!< Minimum value for CIS burst number. */ +#define HCI_MAX_CIS_BN 0x0F /*!< Maximum value for CIS burst number. */ +/**@}*/ + +/** \name CIS Retransmission Number +* +*/ +/**@{*/ +#define HCI_MIN_CIS_RTN 0x00 /*!< Minimum value for CIS retransmission number. */ +#define HCI_MAX_CIS_RTN 0x0F /*!< Maximum value for CIS retransmission number. */ +/**@}*/ + +/** \name ISO Data Path Direction +* +*/ +/**@{*/ +#define HCI_ISO_DATA_DIR_INPUT 0 /*!< Input (Host to Controller) data path. */ +#define HCI_ISO_DATA_DIR_OUTPUT 1 /*!< Output (Controller to Host) data path. */ +/**@}*/ + +/** \name ISO Data Path Direction Bit +* +*/ +/**@{*/ +#define HCI_ISO_DATA_PATH_INPUT_BIT (1<= 199901L)) && \ - (!defined(__ICC8051__) || (__ICC8051__ == 0))) || \ - (defined(__clang__) || defined(_MSC_VER)) || \ - defined(__IAR_SYSTEMS_ICC__) || defined(__ARMCC_VERSION)) + #include -#else -/*! \brief Signed 8-bit value. */ -typedef signed char int8_t; -/*! \brief Unsigned 8-bit value. */ -typedef unsigned char uint8_t; -/*! \brief Signed 16-bit value. */ -typedef signed short int16_t; -/*! \brief Unsigned 16-bit value. */ -typedef unsigned short uint16_t; -/*! \brief Signed 32-bit value. */ -typedef signed long int32_t; -/*! \brief Unsigned 32-bit value. */ -typedef unsigned long uint32_t; -/*! \brief Unsigned 64-bit value. */ -typedef unsigned long long uint64_t; +#include + +#ifndef bool_t + #define bool_t uint8_t #endif -/**@}*/ -/*! \brief Boolean data type */ -typedef uint8_t bool_t; +#ifndef FALSE + #define FALSE 0 +#endif -/*! \} */ /* WSF_TYPES */ +#ifndef TRUE + #define TRUE (!FALSE) +#endif + +/*! \} */ /* Integer Data Types */ #ifdef __cplusplus }; #endif - +/*! \} */ /* WSF_TYPES */ #endif /* WSF_TYPES_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_assert.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_assert.c index b96b6efeebf..d19b942f819 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_assert.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_assert.c @@ -1,29 +1,32 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_assert.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Assert implementation. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Assert implementation. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_assert.h" + #include "wsf_trace.h" -#include "stack/platform/include/pal_sys.h" +#include "pal_sys.h" /************************************************************************************************** Global Variables @@ -35,8 +38,6 @@ * * \param pFile Name of file originating assert. * \param line Line number of assert statement. - * - * \return None. */ /*************************************************************************************************/ #if WSF_TOKEN_ENABLED == TRUE diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_buf.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_buf.c index 4893c467bb2..be2ab9cfc03 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_buf.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_buf.c @@ -1,33 +1,36 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_buf.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Buffer pool service. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Buffer pool service. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_buf.h" -#include "wsf_heap.h" + #include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_trace.h" +#include "wsf_heap.h" #include "wsf_math.h" #include "wsf_os.h" -#include "wsf_trace.h" -#include "wsf_cs.h" /************************************************************************************************** Macros @@ -44,7 +47,7 @@ typedef struct wsfBufMem_tag { struct wsfBufMem_tag *pNext; -#if WSF_BUF_FREE_CHECK == TRUE +#if WSF_BUF_FREE_CHECK_ASSERT == TRUE uint32_t free; #endif } wsfBufMem_t; @@ -290,7 +293,7 @@ void *WsfBufAlloc(uint16_t len) /* Next free buffer is stored inside current free buffer. */ pPool->pFree = pBuf->pNext; -#if WSF_BUF_FREE_CHECK == TRUE +#if WSF_BUF_FREE_CHECK_ASSERT == TRUE pBuf->free = 0; #endif #if WSF_BUF_STATS_HIST == TRUE @@ -366,8 +369,6 @@ void *WsfBufAlloc(uint16_t len) * \brief Free a buffer. * * \param pBuf Buffer to free. - * - * \return None. */ /*************************************************************************************************/ void WsfBufFree(void *pBuf) @@ -378,7 +379,7 @@ void WsfBufFree(void *pBuf) WSF_CS_INIT(cs); /* Verify pointer is within range. */ -#if WSF_BUF_FREE_CHECK == TRUE +#if WSF_BUF_FREE_CHECK_ASSERT == TRUE WSF_ASSERT(p >= ((wsfBufPool_t *) wsfBufMem)->pStart); WSF_ASSERT(p < (wsfBufMem_t *)(((uint8_t *) wsfBufMem) + wsfBufMemLen)); #endif @@ -393,7 +394,7 @@ void WsfBufFree(void *pBuf) /* Enter critical section. */ WSF_CS_ENTER(cs); -#if WSF_BUF_FREE_CHECK == TRUE +#if WSF_BUF_FREE_CHECK_ASSERT == TRUE WSF_ASSERT(p->free != WSF_BUF_FREE_NUM); p->free = WSF_BUF_FREE_NUM; #endif @@ -473,8 +474,6 @@ uint8_t WsfBufGetNumPool(void) * * \param pBuf Buffer to store the statistics. * \param poolId Pool ID. - * - * \return None. */ /*************************************************************************************************/ void WsfBufGetPoolStats(WsfBufPoolStat_t *pStat, uint8_t poolId) @@ -513,8 +512,6 @@ void WsfBufGetPoolStats(WsfBufPoolStat_t *pStat, uint8_t poolId) * \brief Called to register the buffer diagnostics callback function. * * \param pCallback Pointer to the callback function. - * - * \return None. */ /*************************************************************************************************/ void WsfBufDiagRegister(WsfBufDiagCback_t callback) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_bufio.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_bufio.c index 8522ca7300e..3ed43417223 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_bufio.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_bufio.c @@ -1,34 +1,37 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief WSF buffer IO for UART driver. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief WSF buffer IO for UART driver. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include #include "wsf_types.h" -#include "wsf_trace.h" #include "wsf_bufio.h" + #include "wsf_cs.h" +#include "wsf_trace.h" #include "wsf_os.h" -#include "stack/platform/include/pal_uart.h" +#include "pal_uart.h" /************************************************************************************************** Data Types @@ -72,8 +75,6 @@ static struct * \brief Start transmit. * * \param len Length to transmit. - * - * \return None. */ /*************************************************************************************************/ static void wsfBufIoUartTxStart(uint16_t len) @@ -123,8 +124,6 @@ static uint16_t wsfBufIoUartTxBufCount(void) /*************************************************************************************************/ /*! * \brief Rx handler. - * - * \return None. */ /*************************************************************************************************/ static void wsfBufIoUartRxHandler(void) @@ -140,8 +139,6 @@ static void wsfBufIoUartRxHandler(void) /*************************************************************************************************/ /*! * \brief Tx handler. - * - * \return None. */ /*************************************************************************************************/ static void wsfBufIoUartTxHandler(void) @@ -216,9 +213,7 @@ uint32_t WsfBufIoUartInit(void *pBuf, uint32_t size) /*! * \brief Register the UART RX callback. * - * \param Callback function for UART RX. - * - * \return None. + * \param rxCback Callback function for UART RX. */ /*************************************************************************************************/ void WsfBufIoUartRegister(WsfBufIoUartRxCback_t rxCback) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_detoken.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_detoken.c index 058dec65e6e..f29d5cbe074 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_detoken.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_detoken.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Token trace decode. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Token trace decode. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -50,8 +52,6 @@ /*************************************************************************************************/ /*! * \brief Initialize detoken trace. - * - * \return None. */ /*************************************************************************************************/ void WsfDetokenInit() @@ -64,8 +64,6 @@ void WsfDetokenInit() * \brief Enable/disable detoken trace. * * \param enable TRUE to enable, FALSE to disable. - * - * \return None. */ /*************************************************************************************************/ void WsfDetokenEnable(bool_t enable) @@ -85,8 +83,6 @@ void WsfDetokenEnable(bool_t enable) * \brief Find token by id via binary search * * \param token Token identifier. - * - * \return None. */ /*************************************************************************************************/ static const tokenElem_t *wsfDetokenFindToken(uint32_t token) @@ -127,8 +123,6 @@ static const tokenElem_t *wsfDetokenFindToken(uint32_t token) * \brief Find token string by id via binary search * * \param token Token identifier. - * - * \return None. */ /*************************************************************************************************/ static const char *wsfDetokenFindTokenString(uint32_t token) @@ -164,8 +158,6 @@ static const char *wsfDetokenFindTokenString(uint32_t token) * \brief Decode and display HCI Token Trace events * * \param pBuffer Buffer containing HCI event. - * - * \return None. */ /*************************************************************************************************/ static void wsfDetokenDecodeHciTokenTrace(uint8_t *pBuffer) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_efs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_efs.c index 8f35aa440c2..94f64ac6aaa 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_efs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_efs.c @@ -1,31 +1,34 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Embedded File System service. + * \file wsf_efs.c + * + * \brief Embedded File System service. + * + * Copyright (c) 2014-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include #include "wsf_types.h" #include "wsf_efs.h" + #include "wsf_assert.h" -#include "wsf_trace.h" #include "wsf_cs.h" +#include "wsf_trace.h" #include "util/bstream.h" /* Media Control Block */ @@ -300,7 +303,7 @@ uint8_t WsfEfsErase(wsfEfsHandle_t handle) uint32_t address = pFile->address; uint32_t size = pFile->maxSize; - status = wsfEfsMediaTbl[media]->erase(address, size); + status = wsfEfsMediaTbl[media]->erase((uint8_t *) address, size); pFile->size = 0; } } @@ -393,7 +396,7 @@ uint16_t WsfEfsGet(wsfEfsHandle_t handle, uint32_t offset, uint8_t *pBuffer, uin len = (uint16_t) (pFile->size - offset); } - wsfEfsMediaTbl[media]->read(pBuffer, address, len); + wsfEfsMediaTbl[media]->read(pBuffer, (uint8_t *) address, len); return len; } @@ -442,7 +445,7 @@ uint16_t WsfEfsPut(wsfEfsHandle_t handle, uint32_t offset, const uint8_t *pBuffe len = (uint16_t) (pFile->maxSize - offset); } - wsfEfsMediaTbl[media]->write(pBuffer, address, len); + wsfEfsMediaTbl[media]->write(pBuffer, (uint8_t *) address, len); /* If writing to the end of the file, update the file size */ if (offset + len > pFile->size) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c index 8a4425b5d6f..cb5a444969c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c @@ -1,33 +1,35 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_heap.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Heap service. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Heap service. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" -#include "wsf_buf.h" #include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_trace.h" +#include "wsf_buf.h" #include "wsf_math.h" #include "wsf_os.h" -#include "wsf_trace.h" -#include "wsf_cs.h" -#include "stack/platform/include/pal_sys.h" +#include "pal_sys.h" /************************************************************************************************** Global Variables @@ -43,8 +45,6 @@ extern unsigned long __heap_start__; * \brief Reserve heap memory. * * \param size Number of bytes of heap memory used. - * - * \return None */ /*************************************************************************************************/ void WsfHeapAlloc(uint32_t size) @@ -89,5 +89,9 @@ uint32_t WsfHeapCountAvailable(void) /*************************************************************************************************/ uint32_t WsfHeapCountUsed(void) { +#ifdef __GNUC__ + return ((uint8_t *)&__heap_end__ - (uint8_t *)&__heap_start__) - SystemHeapSize; +#else return 0; +#endif } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_msg.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_msg.c index 4c1dbc00242..4f5f4144fac 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_msg.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_msg.c @@ -1,31 +1,33 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \brief Message passing service. + * \file wsf_msg.c + * + * \brief Message passing service. + * + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_msg.h" #include "wsf_assert.h" +#include "wsf_trace.h" #include "wsf_buf.h" #include "wsf_queue.h" -#include "wsf_trace.h" #include "wsf_os.h" /************************************************************************************************** @@ -83,8 +85,6 @@ void *WsfMsgAlloc(uint16_t len) * \brief Free a message buffer allocated with WsfMsgAlloc(). * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ void WsfMsgFree(void *pMsg) @@ -98,8 +98,6 @@ void WsfMsgFree(void *pMsg) * * \param handlerId Event handler ID. * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ void WsfMsgSend(wsfHandlerId_t handlerId, void *pMsg) @@ -120,8 +118,6 @@ void WsfMsgSend(wsfHandlerId_t handlerId, void *pMsg) * \param pQueue Pointer to queue. * \param handerId Set message handler ID to this value. * \param pElem Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ void WsfMsgEnq(wsfQueue_t *pQueue, wsfHandlerId_t handlerId, void *pMsg) @@ -188,3 +184,34 @@ void *WsfMsgPeek(wsfQueue_t *pQueue, wsfHandlerId_t *pHandlerId) return pMsg; } + +/*************************************************************************************************/ +/*! + * \brief Get the Nth message without removing it from the queue. + * + * \param pQueue Pointer to queue. + * \param n Nth item from the top (0 = top element). + * \param pHandlerId Handler ID of returned message; this is a return parameter. + * + * \return Pointer to the next message on the queue or NULL if queue is empty. + */ +/*************************************************************************************************/ +void *WsfMsgNPeek(wsfQueue_t *pQueue, uint8_t n, wsfHandlerId_t *pHandlerId) +{ + wsfMsg_t *pMsg = pQueue->pHead; + + while (pMsg && n--) + { + pMsg = pMsg->pNext; + } + + if (pMsg != NULL) + { + *pHandlerId = pMsg->handlerId; + + /* hide header */ + pMsg++; + } + + return pMsg; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c index 66734d6b0cb..4d1a268c940 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_nvm.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief NVM service. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief NVM service. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" -#include "wsf_assert.h" #include "wsf_nvm.h" -#include "stack/platform/include/pal_nvm.h" +#include "wsf_assert.h" +#include "pal_flash.h" #include "util/crc32.h" /************************************************************************************************** @@ -34,15 +36,18 @@ #define WSF_NVM_START_ADDR 0x0000 /*! Reserved filecode. */ -#define WSF_NVM_RESERVED_FILECODE ((uint32_t)0) +#define WSF_NVM_RESERVED_FILECODE ((uint64_t)0) /* Unused (erased) filecode. */ /* TODO: May depend on flash type */ -#define WSF_NVM_UNUSED_FILECODE ((uint32_t)0xFFFFFFFF) +#define WSF_NVM_UNUSED_FILECODE ((uint64_t)0xFFFFFFFFFFFFFFFF) + +/*! Flash word size. */ +#define WSF_FLASH_WORD_SIZE 4 /*! Align value to word boundary. */ -#define WSF_NVM_WORD_ALIGN(x) (((x) + (PAL_NVM_WORD_SIZE - 1)) & \ - ~(PAL_NVM_WORD_SIZE - 1)) +#define WSF_NVM_WORD_ALIGN(x) (((x) + (WSF_FLASH_WORD_SIZE - 1)) & \ + ~(WSF_FLASH_WORD_SIZE - 1)) #define WSF_NVM_CRC_INIT_VALUE 0xFEDCBA98 @@ -53,12 +58,19 @@ /*! \brief Header. */ typedef struct { - uint32_t id; /*!< Stored data ID. */ + uint64_t id; /*!< Stored data ID. */ uint32_t len; /*!< Stored data length. */ uint32_t headerCrc; /*!< CRC of this header. */ uint32_t dataCrc; /*!< CRC of subsequent data. */ } WsfNvmHeader_t; +static struct +{ + uint32_t availAddr; /*!< Next available address for NVM write. */ + uint32_t sectorSize; /*!< Size of erase sector. */ + uint32_t totalSize; /*!< Total size of NVM storage. */ +} wsfNvmCb; + /************************************************************************************************** Global Functions **************************************************************************************************/ @@ -66,13 +78,84 @@ typedef struct /*************************************************************************************************/ /*! * \brief Initialize the WSF NVM. - * - * \return None. */ /*************************************************************************************************/ void WsfNvmInit(void) { - PalNvmInit(NULL); + PalFlashInit(NULL); + wsfNvmCb.totalSize = PalNvmGetTotalSize(); + wsfNvmCb.sectorSize = PalNvmGetSectorSize(); + + WsfNvmHeader_t header; + uint32_t storageAddr = WSF_NVM_START_ADDR; + uint32_t headerCrc; + bool_t corruptData = FALSE; + + do + { + /* Read header. */ + PalFlashRead(&header, sizeof(header), storageAddr); + + if (header.id == WSF_NVM_UNUSED_FILECODE) + { + /* Found unused entry at end of used storage. */ + break; + } + + /* Iterate through stored data headers, looking for existing matching stored data header. */ + if (header.id != WSF_NVM_RESERVED_FILECODE) + { + /* Calculate CRC of header itself. */ + headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), + (uint8_t *)&header); + + if (headerCrc != header.headerCrc) + { + /* Corrupt header. */ + corruptData = TRUE; + break; + } + } + else + { + if ((header.headerCrc != 0) || (header.dataCrc !=0)) + { + /* Corrupt header. */ + corruptData = TRUE; + break; + } + } + + /* Move to next stored data block and read header. */ + storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); + WSF_ASSERT((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize); + + } while ((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize); + + wsfNvmCb.availAddr = storageAddr; + + /* Check for corrupt data. */ + if (corruptData == TRUE) + { + /* Search for the first available location */ + while ((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize) + { + PalFlashRead(&header.id, sizeof(header.id), storageAddr); + + if (header.id == WSF_NVM_UNUSED_FILECODE) + { + break; + } + + storageAddr += sizeof(header.id); + } + + /* Update the address of the first available location. align to sector boundary. */ + wsfNvmCb.availAddr = (storageAddr + wsfNvmCb.sectorSize - 1) & ~(wsfNvmCb.sectorSize - 1); + + /* Erase all data. */ + WsfNvmEraseDataAll(NULL); + } } /*************************************************************************************************/ @@ -84,10 +167,10 @@ void WsfNvmInit(void) * \param len Data length to read. * \param compCback Read callback. * - * \return if Read NVM successfully. + * \return TRUE if NVM operation is successful, FALSE otherwise. */ /*************************************************************************************************/ -bool_t WsfNvmReadData(uint32_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) +bool_t WsfNvmReadData(uint64_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) { WsfNvmHeader_t header; uint32_t headerCrc, dataCrc; @@ -97,7 +180,7 @@ bool_t WsfNvmReadData(uint32_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); /* Read first header. */ - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); do { @@ -124,7 +207,7 @@ bool_t WsfNvmReadData(uint32_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent { /* Valid header and matching ID - read data after header. */ storageAddr += sizeof(header); - PalNvmRead(pData, header.len, storageAddr); + PalFlashRead(pData, header.len, storageAddr); dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, header.len, pData); if (dataCrc == header.dataCrc) { @@ -136,7 +219,7 @@ bool_t WsfNvmReadData(uint32_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent /* Move to next stored data block and read header. */ storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); } while(1); if (compCback) @@ -155,19 +238,20 @@ bool_t WsfNvmReadData(uint32_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent * \param len Data length to write. * \param compCback Write callback. * - * \return if write NVM successfully. + * \return TRUE if NVM operation is successful, FALSE otherwise. */ /*************************************************************************************************/ -bool_t WsfNvmWriteData(uint32_t id, const uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) +bool_t WsfNvmWriteData(uint64_t id, const uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) { WsfNvmHeader_t header; - uint32_t headerCrc; + uint32_t headerCrc, dataCrc; uint32_t storageAddr = WSF_NVM_START_ADDR; WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); + WSF_ASSERT((wsfNvmCb.availAddr - WSF_NVM_START_ADDR) <= wsfNvmCb.totalSize); /* Read first header. */ - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); do { @@ -192,17 +276,29 @@ bool_t WsfNvmWriteData(uint32_t id, const uint8_t *pData, uint16_t len, WsfNvmCo } else if (header.id == id) { - /* Valid header and matching ID - scratch header out. */ - header.id = WSF_NVM_RESERVED_FILECODE; - header.headerCrc = 0; - header.dataCrc = 0; - PalNvmWrite(&header, sizeof(header), storageAddr); + dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, len, pData); + if (dataCrc == header.dataCrc) + { + if (compCback) + { + compCback(TRUE); + } + return TRUE; + } + else + { + /* Valid header and matching ID - scratch header out. */ + header.id = WSF_NVM_RESERVED_FILECODE; + header.headerCrc = 0; + header.dataCrc = 0; + PalFlashWrite(&header, sizeof(header), storageAddr); + } } } /* Move to next stored data block and read header. */ storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); } while(1); /* After cycling through all headers, create a new stored data header and store data */ @@ -211,12 +307,19 @@ bool_t WsfNvmWriteData(uint32_t id, const uint8_t *pData, uint16_t len, WsfNvmCo header.headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), (uint8_t *)&header); header.dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, len, pData); - PalNvmWrite(&header, sizeof(header), storageAddr); - PalNvmWrite((void *)pData, len, storageAddr + sizeof(header)); + + PalFlashWrite(&header, sizeof(header), storageAddr); + PalFlashWrite((void *)pData, len, storageAddr + sizeof(header)); + + /* Move to next empty flash. */ + storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); + wsfNvmCb.availAddr = storageAddr; + if (compCback) { - compCback(TRUE); + compCback((wsfNvmCb.availAddr - WSF_NVM_START_ADDR) <= wsfNvmCb.totalSize); } + return TRUE; } @@ -227,10 +330,10 @@ bool_t WsfNvmWriteData(uint32_t id, const uint8_t *pData, uint16_t len, WsfNvmCo * \param id Erase ID. * \param compCback Write callback. * - * \return if erase NVM successfully. + * \return TRUE if NVM operation is successful, FALSE otherwise. */ /*************************************************************************************************/ -bool_t WsfNvmEraseData(uint32_t id, WsfNvmCompEvent_t compCback) +bool_t WsfNvmEraseData(uint64_t id, WsfNvmCompEvent_t compCback) { WsfNvmHeader_t header; uint32_t headerCrc; @@ -240,7 +343,7 @@ bool_t WsfNvmEraseData(uint32_t id, WsfNvmCompEvent_t compCback) WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); /* Read first header. */ - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); do { @@ -267,14 +370,14 @@ bool_t WsfNvmEraseData(uint32_t id, WsfNvmCompEvent_t compCback) header.id = WSF_NVM_RESERVED_FILECODE; header.headerCrc = 0; header.dataCrc = 0; - PalNvmWrite(&header, sizeof(header), storageAddr); + PalFlashWrite(&header, sizeof(header), storageAddr); erased = TRUE; } } /* Move to next stored data block and read header. */ storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalNvmRead(&header, sizeof(header), storageAddr); + PalFlashRead(&header, sizeof(header), storageAddr); } while(1); if (compCback) @@ -286,17 +389,20 @@ bool_t WsfNvmEraseData(uint32_t id, WsfNvmCompEvent_t compCback) /*************************************************************************************************/ /*! - * \brief Erase sectors. + * \brief Erase all data located in NVM storage. * - * \param numOfSectors Number of sectors to be erased. * \param compCback Erase callback. * - * \return if erase NVM successfully. + * \note Security Risk Warning. NVM storage could be shared by multiple Apps. */ /*************************************************************************************************/ -void WsfNvmEraseSector(uint32_t numOfSectors, WsfNvmCompEvent_t compCback) +void WsfNvmEraseDataAll(WsfNvmCompEvent_t compCback) { - PalNvmEraseSector(numOfSectors * PAL_NVM_SECTOR_SIZE, WSF_NVM_START_ADDR); + for (uint32_t eraseAddr = WSF_NVM_START_ADDR; eraseAddr < wsfNvmCb.availAddr; eraseAddr += wsfNvmCb.sectorSize) + { + PalFlashEraseSector(1, eraseAddr); + } + wsfNvmCb.availAddr = WSF_NVM_START_ADDR; if (compCback) { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_os_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_os_int.h deleted file mode 100644 index bd77942525b..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_os_int.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Software foundation OS platform-specific interface file. - */ -/*************************************************************************************************/ -#ifndef WSF_OS_INT_H -#define WSF_OS_INT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/* Task events */ -#define WSF_MSG_QUEUE_EVENT 0x01 /* Message queued for event handler */ -#define WSF_TIMER_EVENT 0x02 /* Timer expired for event handler */ -#define WSF_HANDLER_EVENT 0x04 /* Event set for event handler */ - -/* Derive task from handler ID */ -#define WSF_TASK_FROM_ID(handlerID) (((handlerID) >> 4) & 0x0F) - -/* Derive handler from handler ID */ -#define WSF_HANDLER_FROM_ID(handlerID) ((handlerID) & 0x0F) - -/************************************************************************************************** - Data Types -**************************************************************************************************/ - -/* Event handler ID data type */ -typedef uint8_t wsfHandlerId_t; - -/* Event handler event mask data type */ -typedef uint8_t wsfEventMask_t; - -/* Task ID data type */ -typedef wsfHandlerId_t wsfTaskId_t; - -/* Task event mask data type */ -typedef uint8_t wsfTaskEvent_t; - -/************************************************************************************************** - Function Declarations -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Check if WSF is ready to sleep. - * - * \return Return TRUE if there are no pending WSF task events set, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t wsfOsReadyToSleep(void); - -/*************************************************************************************************/ -/*! - * \brief Event dispatched. Designed to be called repeatedly from infinite loop. - * - * \return None. - */ -/*************************************************************************************************/ -void wsfOsDispatcher(void); - -#ifdef __cplusplus -}; -#endif - -#endif /* WSF_OS_INT_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_queue.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_queue.c index 49ff22747cd..bf8ecebc4c3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_queue.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_queue.c @@ -1,27 +1,30 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_queue.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief General purpose queue service. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief General purpose queue service. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_queue.h" + #include "wsf_assert.h" #include "wsf_cs.h" @@ -48,8 +51,6 @@ typedef struct wsfQueueElem_tag * * \param pQueue Pointer to queue. * \param pElem Pointer to element. - * - * \return None. */ /*************************************************************************************************/ void WsfQueueEnq(wsfQueue_t *pQueue, void *pElem) @@ -125,12 +126,10 @@ void *WsfQueueDeq(wsfQueue_t *pQueue) /*************************************************************************************************/ /*! - * \brief Push and element to the head of a queue. + * \brief Push an element to the head of a queue. * * \param pQueue Pointer to queue. * \param pElem Pointer to element. - * - * \return None. */ /*************************************************************************************************/ void WsfQueuePush(wsfQueue_t *pQueue, void *pElem) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c index 3ed48a4360e..df2c9dd1e94 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c @@ -1,34 +1,37 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_timer.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Timer service. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Timer service. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_queue.h" #include "wsf_timer.h" + #include "wsf_assert.h" #include "wsf_cs.h" #include "wsf_trace.h" -#include "stack/platform/include/pal_rtc.h" -#include "stack/platform/include/pal_led.h" -#include "stack/platform/include/pal_sys.h" +#include "pal_rtc.h" +#include "pal_led.h" +#include "pal_sys.h" /************************************************************************************************** Macros @@ -49,9 +52,9 @@ /* convert seconds to timer ticks */ #define WSF_TIMER_SEC_TO_TICKS(sec) (1000 * (sec) + 1) -/* convert milliseconds to timer ticks */ -/* Extra tick should be added to guarantee waiting time is longer than the specified ms. */ -#define WSF_TIMER_MS_TO_TICKS(ms) ((uint64_t)ms + 1) +/*! \brief Convert milliseconds to timer ticks. */ +/*! \brief Extra tick should be added to guarantee waiting time is longer than the specified ms. */ +#define WSF_TIMER_MS_TO_TICKS(ms) ((uint64_t)(ms) + 1) #define WSF_TIMER_TICKS_PER_SEC (1000) @@ -83,7 +86,7 @@ * Calculate elapsed ticks since last WSF timer update, with remainder; * since the RTC timer is 24 bit set the 24th bit to handle any underflow. */ -#define WSF_TIMER_RTC_ELAPSED_TICKS(x) ((PAL_MAX_RTC_COUNTER_VAL + 1 + x - wsfTimerRtcLastTicks \ +#define WSF_TIMER_RTC_ELAPSED_TICKS(x) ((PAL_MAX_RTC_COUNTER_VAL + 1 + (x) - wsfTimerRtcLastTicks \ + wsfTimerRtcRemainder) & PAL_MAX_RTC_COUNTER_VAL) /************************************************************************************************** @@ -103,8 +106,6 @@ static uint32_t wsfTimerRtcRemainder = 0; * \brief Remove a timer from queue. Note this function does not lock task scheduling. * * \param pTimer Pointer to timer. - * - * \return None. */ /*************************************************************************************************/ static void wsfTimerRemove(wsfTimer_t *pTimer) @@ -140,8 +141,6 @@ static void wsfTimerRemove(wsfTimer_t *pTimer) * * \param pTimer Pointer to timer. * \param ticks Timer ticks until expiration. - * - * \return None. */ /*************************************************************************************************/ static void wsfTimerInsert(wsfTimer_t *pTimer, wsfTimerTicks_t ticks) @@ -196,19 +195,48 @@ static uint32_t wsfTimerTicksToRtc(wsfTimerTicks_t wsfTicks) return ((numSec * PAL_RTC_TICKS_PER_SEC) + (remainder * WSF_TIMER_RTC_TICKS_PER_WSF_TICK)); } +/*************************************************************************************************/ +/*! + * \brief Return the number of ticks until the next timer expiration. Note that this + * function can return zero even if a timer is running, indicating a timer + * has expired but has not yet been serviced. + * + * \return The number of ticks until the next timer expiration. + */ +/*************************************************************************************************/ +static wsfTimerTicks_t wsfTimerNextExpiration(void) +{ + wsfTimerTicks_t ticks; + + /* task schedule lock */ + WsfTaskLock(); + + if (wsfTimerTimerQueue.pHead == NULL) + { + ticks = 0; + } + else + { + ticks = ((wsfTimer_t *) wsfTimerTimerQueue.pHead)->ticks; + } + + /* task schedule unlock */ + WsfTaskUnlock(); + + return ticks; +} + /*************************************************************************************************/ /*! * \brief Initialize the timer service. This function should only be called once * upon system initialization. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerInit(void) { WSF_QUEUE_INIT(&wsfTimerTimerQueue); - wsfTimerRtcLastTicks = 0; + wsfTimerRtcLastTicks = PalRtcCounterGet(); wsfTimerRtcRemainder = 0; } @@ -218,8 +246,6 @@ void WsfTimerInit(void) * * \param pTimer Pointer to timer. * \param sec Seconds until expiration. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerStartSec(wsfTimer_t *pTimer, wsfTimerTicks_t sec) @@ -236,8 +262,6 @@ void WsfTimerStartSec(wsfTimer_t *pTimer, wsfTimerTicks_t sec) * * \param pTimer Pointer to timer. * \param ms Milliseconds until expiration. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerStartMs(wsfTimer_t *pTimer, wsfTimerTicks_t ms) @@ -253,8 +277,6 @@ void WsfTimerStartMs(wsfTimer_t *pTimer, wsfTimerTicks_t ms) * \brief Stop a timer. * * \param pTimer Pointer to timer. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerStop(wsfTimer_t *pTimer) @@ -275,8 +297,6 @@ void WsfTimerStop(wsfTimer_t *pTimer) * \brief Update the timer service with the number of elapsed ticks. * * \param ticks Number of ticks since last update. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerUpdate(wsfTimerTicks_t ticks) @@ -311,41 +331,6 @@ void WsfTimerUpdate(wsfTimerTicks_t ticks) WsfTaskUnlock(); } -/*************************************************************************************************/ -/*! - * \brief Return the number of ticks until the next timer expiration. Note that this - * function can return zero even if a timer is running, indicating a timer - * has expired but has not yet been serviced. - * - * \param pTimerRunning Returns TRUE if a timer is running, FALSE if no timers running. - * - * \return The number of ticks until the next timer expiration. - */ -/*************************************************************************************************/ -wsfTimerTicks_t WsfTimerNextExpiration(bool_t *pTimerRunning) -{ - wsfTimerTicks_t ticks; - - /* task schedule lock */ - WsfTaskLock(); - - if (wsfTimerTimerQueue.pHead == NULL) - { - *pTimerRunning = FALSE; - ticks = 0; - } - else - { - *pTimerRunning = TRUE; - ticks = ((wsfTimer_t *) wsfTimerTimerQueue.pHead)->ticks; - } - - /* task schedule unlock */ - WsfTaskUnlock(); - - return ticks; -} - /*************************************************************************************************/ /*! * \brief Service expired timers for the given task. @@ -394,14 +379,11 @@ wsfTimer_t *WsfTimerServiceExpired(wsfTaskId_t taskId) /*! * \brief Function for checking if there is an active timer and if there is enough time to * go to sleep and going to sleep. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerSleep(void) { wsfTimerTicks_t nextExpiration; - bool_t timerRunning; /* If PAL system is busy, no need to sleep. */ if (PalSysIsBusy()) @@ -409,9 +391,9 @@ void WsfTimerSleep(void) return; } - nextExpiration = WsfTimerNextExpiration(&timerRunning); + nextExpiration = wsfTimerNextExpiration(); - if (timerRunning && (nextExpiration > 0)) + if (nextExpiration > 0) { uint32_t awake = wsfTimerTicksToRtc(nextExpiration); uint32_t rtcCurrentTicks = PalRtcCounterGet(); @@ -423,20 +405,20 @@ void WsfTimerSleep(void) uint32_t compareVal = (rtcCurrentTicks + awake - elapsed) & PAL_MAX_RTC_COUNTER_VAL; /* set RTC timer compare */ - PalRtcCompareSet(compareVal); + PalRtcCompareSet(0, compareVal); /* enable RTC interrupt */ - PalRtcEnableCompareIrq(); + PalRtcEnableCompareIrq(0); /* one final check for OS activity then enter sleep */ - WSF_CS_ENTER(cs); - if (wsfOsReadyToSleep() && (PalRtcCounterGet() != PalRtcCompareGet())) + PalEnterCs(); + if (wsfOsReadyToSleep()) { PalLedOff(PAL_LED_ID_CPU_ACTIVE); PalSysSleep(); PalLedOn(PAL_LED_ID_CPU_ACTIVE); } - WSF_CS_EXIT(cs); + PalExitCs(); } else { @@ -447,26 +429,23 @@ void WsfTimerSleep(void) else { /* disable RTC interrupt */ - PalRtcDisableCompareIrq(); + PalRtcDisableCompareIrq(0); /* one final check for OS activity then enter sleep */ - WSF_CS_ENTER(cs); + PalEnterCs(); if (wsfOsReadyToSleep()) { PalLedOff(PAL_LED_ID_CPU_ACTIVE); PalSysSleep(); PalLedOn(PAL_LED_ID_CPU_ACTIVE); } - WSF_CS_EXIT(cs); + PalExitCs(); } } - /*************************************************************************************************/ /*! * \brief Function for updating WSF timer based on elapsed RTC ticks. - * - * \return None. */ /*************************************************************************************************/ void WsfTimerSleepUpdate(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_trace.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_trace.c index 2e99669773c..41c8ba07140 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_trace.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_trace.c @@ -1,34 +1,37 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Trace message implementation. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Trace message implementation. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" #include "wsf_trace.h" + #include "wsf_bufio.h" -#include "wsf_assert.h" #include "wsf_buf.h" -#include "wsf_cs.h" #include "util/print.h" -#include "stack/platform/include/pal_sys.h" +#include "pal_sys.h" #include +#include "wsf_assert.h" +#include "wsf_cs.h" /************************************************************************************************** Macros @@ -44,7 +47,7 @@ #ifndef WSF_TOKEN_RING_BUF_SIZE /*! \brief Size of token ring buffer (multiple of 2^N). */ -#define WSF_TOKEN_RING_BUF_SIZE 32 +#define WSF_TOKEN_RING_BUF_SIZE 64 #endif /*! \brief Ring buffer flow control condition detected. */ @@ -89,8 +92,6 @@ struct * * \param tok Message token. * \param param Message parameter. - * - * \return None. */ /*************************************************************************************************/ void WsfToken(uint32_t tok, uint32_t param) @@ -181,8 +182,6 @@ uint8_t wsfTraceOverFlowMessage(char *pBuf, const char *pStr, ...) * * \param pStr Format string * Addition parameters variable arguments to the format string. - * - * \return None. */ /*************************************************************************************************/ void WsfTrace(const char *pStr, ...) @@ -240,8 +239,6 @@ void WsfTrace(const char *pStr, ...) * \brief Enable trace messages. * * \param enable TRUE to enable, FALSE to disable - * - * \return None. */ /*************************************************************************************************/ void WsfTraceEnable(bool_t enable) @@ -264,8 +261,6 @@ void WsfTraceEnable(bool_t enable) * * \param traceCback Token event handler. * - * \return None. - * * This routine registers trace output handler. This callback is called when the trace data is * ready for writing. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bda.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bda.c index 53b204bf946..90d901b96e1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bda.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bda.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file bda.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Bluetooth device address utilities. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Bluetooth device address utilities. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,8 +32,6 @@ * * \param pDst Pointer to destination. * \param pSrc Pointer to source. - * - * \return None. */ /*************************************************************************************************/ void BdaCpy(uint8_t *pDst, const uint8_t *pSrc) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bstream.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bstream.c index 2d1bc5cd25f..6cf5d948193 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bstream.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/bstream.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file bstream.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Byte stream to integer conversion functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Byte stream to integer conversion functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -50,8 +52,6 @@ uint64_t BstreamToUint64(const uint8_t *p) * * \param p Bstream pointer. * \param n uint64_t number. - * - * \return None. */ /*************************************************************************************************/ void Uint64ToBstream(uint8_t *p, uint64_t n) @@ -91,8 +91,6 @@ uint64_t BstreamToBda64(const uint8_t *p) * * \param p Bstream pointer. * \param bda uint64_t BDA. - * - * \return None. */ /*************************************************************************************************/ void Bda64ToBstream(uint8_t *p, uint64_t bda) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/calc128.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/calc128.c index 1b7d95c375e..1c2048adca2 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/calc128.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/calc128.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file calc128.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief 128-bit integer utilities. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief 128-bit integer utilities. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -41,8 +43,6 @@ const uint8_t calc128Zeros[CALC128_LEN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 * * \param pDst Pointer to destination. * \param pSrc Pointer to source. - * - * \return None. */ /*************************************************************************************************/ void Calc128Cpy(uint8_t *pDst, uint8_t *pSrc) @@ -56,8 +56,6 @@ void Calc128Cpy(uint8_t *pDst, uint8_t *pSrc) * * \param pDst Pointer to destination. * \param pSrc Pointer to source. - * - * \return None. */ /*************************************************************************************************/ void Calc128Cpy64(uint8_t *pDst, uint8_t *pSrc) @@ -71,8 +69,6 @@ void Calc128Cpy64(uint8_t *pDst, uint8_t *pSrc) * * \param pDst Pointer to destination. * \param pSrc Pointer to source. - * - * \return None. */ /*************************************************************************************************/ void Calc128Xor(uint8_t *pDst, uint8_t *pSrc) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/crc32.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/crc32.c index 954245995d5..5cbeb11179f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/crc32.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/crc32.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file crc32.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief CRC-32 utilities. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief CRC-32 utilities. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -119,8 +121,6 @@ static const uint32_t crc32Table[256] = * \param len Length of the buffer. * \param pBuf Buffer to compute the CRC. * - * \return None. - * * This routine was originally generated with crcmod.py using the following parameters: * - polynomial 0x104C11DB7 * - bit reverse algorithm diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/fcs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/fcs.c index 02750447202..399f6b4f75b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/fcs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/fcs.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file fcs.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief FCS utilities (3GPP TS 27.010). * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2010-2017 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief FCS utilities (3GPP TS 27.010). + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/prand.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/prand.c index 02aa3f20206..2911eb6684c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/prand.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/prand.c @@ -1,29 +1,31 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file prand.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Pseudo-random number generator interface. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * ARM confidential and proprietary. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Pseudo-random number generator interface. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "wsf_types.h" -#include "util/bstream.h" - #include "util/prand.h" +#include "util/bstream.h" /************************************************************************************************** Global Variables @@ -41,8 +43,6 @@ static struct /*************************************************************************************************/ /*! * \brief Initialize random number generator. - * - * \return None. */ /*************************************************************************************************/ void PrandInit(void) @@ -84,8 +84,6 @@ static uint32_t prandNum(void) * * \param pBuf Buffer. * \param len Length of buffer in bytes. - * - * \return None. */ /*************************************************************************************************/ void PrandGen(uint8_t *pBuf, uint16_t len) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/print.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/print.c index 391bb038096..eeee907cf35 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/print.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/print.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file print.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Utility functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2015-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Utility functions. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/terminal.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/terminal.c index 0a9bebe3fc6..7d97f548ff7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/terminal.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/terminal.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file terminal.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Terminal handler. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2015-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief Terminal handler. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -24,12 +26,13 @@ #include #include +#include "wsf_types.h" #include "util/terminal.h" -#include "util/print.h" -#include "wsf_types.h" #include "wsf_assert.h" #include "wsf_trace.h" +#include "util/print.h" + #include "util/bstream.h" /************************************************************************************************** @@ -89,8 +92,6 @@ static terminalCommand_t terminalCommandEcho = { NULL, "echo", "echo ", * \brief Initialize terminal. * * \param handlerId Handler ID for TerminalHandler(). - * - * \return None. */ /*************************************************************************************************/ void TerminalInit(wsfHandlerId_t handlerId) @@ -110,8 +111,6 @@ void TerminalInit(wsfHandlerId_t handlerId) /*************************************************************************************************/ /*! * \brief Register the UART Tx Function for the platform. - * - * \return None. */ /*************************************************************************************************/ void TerminalRegisterUartTxFunc(terminalUartTx_t uartTxFunc) @@ -124,8 +123,6 @@ void TerminalRegisterUartTxFunc(terminalUartTx_t uartTxFunc) * \brief Register command with terminal. * * \param pCommand Command. - * - * \return None. */ /*************************************************************************************************/ void TerminalRegisterCommand(terminalCommand_t *pCommand) @@ -154,8 +151,6 @@ void TerminalRegisterCommand(terminalCommand_t *pCommand) * \brief Execute a received command. * * \param pBuf Command string. - * - * \return None. */ /*************************************************************************************************/ static void terminalExecute(char *pBuf) @@ -297,8 +292,6 @@ static void terminalExecute(char *pBuf) * * \param event WSF event mask. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void TerminalHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) @@ -320,8 +313,6 @@ void TerminalHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) * \brief Called by application when a data byte is received. * * \param dataByte Received byte. - * - * \return None. */ /*************************************************************************************************/ void TerminalRx(uint8_t dataByte) @@ -373,8 +364,6 @@ void TerminalRx(uint8_t dataByte) * \brief Called by application to transmit string. * * \param pStr String. - * - * \return None. */ /*************************************************************************************************/ void TerminalTxStr(const char *pStr) @@ -387,8 +376,6 @@ void TerminalTxStr(const char *pStr) * \brief Called by application to transmit character. * * \param c Character. - * - * \return None. */ /*************************************************************************************************/ void TerminalTxChar(char c) @@ -402,8 +389,6 @@ void TerminalTxChar(char c) * * \param pStr Message format string * \param ... Additional arguments, printf-style - * - * \return None. */ /*************************************************************************************************/ void TerminalTxPrint(const char *pStr, ...) @@ -460,8 +445,6 @@ static uint8_t terminalCommandHelpHandler(uint32_t argc, char **argv) * * \param pBuf Buffer to transmit. * \param len Length of buffer in octets. - * - * \return None. */ /*************************************************************************************************/ void TerminalTx(const uint8_t *pData, uint16_t len) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/wstr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/wstr.c index f6406a46239..26db5a8e893 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/wstr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/util/wstr.c @@ -1,22 +1,24 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wstr.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief String manipulation functions. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2014-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \brief String manipulation functions. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -55,8 +57,6 @@ void WstrnCpy(char *pBuf, const char *pData, uint8_t n) * \param pBuf1 Buffer to hold reversed copy. * \param pBuf2 Buffer to copy. * \param len Size of pBuf1 and pBuf2 in bytes. - * - * \return None. */ /*************************************************************************************************/ void WStrReverseCpy(uint8_t *pBuf1, const uint8_t *pBuf2, uint16_t len) @@ -75,8 +75,6 @@ void WStrReverseCpy(uint8_t *pBuf1, const uint8_t *pBuf2, uint16_t len) * * \param pBuf Buffer to reverse. * \param len size of pBuf in bytes. - * - * \return None. */ /*************************************************************************************************/ void WStrReverse(uint8_t *pBuf, uint8_t len) @@ -98,8 +96,6 @@ void WStrReverse(uint8_t *pBuf, uint8_t len) * \param pBuf Storage for string representation of value. * \param val Value. * \param len Length of value, in bits. - * - * \return None. */ /*************************************************************************************************/ void WStrFormatHex(char *pBuf, uint32_t val, uint8_t len) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c index 8bf33a4d482..412177d965a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c @@ -1,52 +1,44 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file hci_tr.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI transport module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ +/*************************************************************************************************/ +#include #include "wsf_types.h" #include "wsf_msg.h" -#include "wsf_trace.h" -#include "wsf_assert.h" #include "util/bstream.h" #include "hci_api.h" #include "hci_core.h" -#include "hci_drv.h" - +#include "hci_tr.h" -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#define HCI_HDR_LEN_MAX HCI_ACL_HDR_LEN - -/************************************************************************************************** - Data Types -**************************************************************************************************/ - -typedef enum -{ - HCI_RX_STATE_IDLE, - HCI_RX_STATE_HEADER, - HCI_RX_STATE_DATA, - HCI_RX_STATE_COMPLETE -} hciRxState_t; +#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) +#include "ll_api.h" +#endif /*************************************************************************************************/ /*! * \fn hciTrSendAclData - * - * \brief Send a complete HCI ACL packet to the transport. + * + * \brief Send a complete HCI ACL packet to the transport. * * \param pContext Connection context. * \param pData WSF msg buffer containing an ACL packet. @@ -56,214 +48,53 @@ typedef enum /*************************************************************************************************/ void hciTrSendAclData(void *pContext, uint8_t *pData) { - uint16_t len; - - /* get 16-bit length */ - BYTES_TO_UINT16(len, &pData[2]); - len += HCI_ACL_HDR_LEN; + uint16_t len; + uint8_t *p; - /* dump event for protocol analysis */ - HCI_PDUMP_TX_ACL(len, pData); - - /* transmit ACL header and data */ - if (hciDrvWrite(HCI_ACL_TYPE, len, pData) == len) + /* if fragmenting */ + if (hciCoreTxAclDataFragmented(pContext)) { -#if CORDIO_ZERO_COPY_HCI - /* pData is not freed as the hciDrvWrite took ownership of the WSF buffer */ -#else - /* free buffer */ - hciCoreTxAclComplete((hciCoreConn_t *)pContext, pData); -#endif // CORDIO_ZERO_COPY_HCI - } -} - + /* get 16-bit length */ + BYTES_TO_UINT16(len, (pData + 2)) + len += HCI_ACL_HDR_LEN; -/*************************************************************************************************/ -/*! - * \fn hciTrSendCmd - * - * \brief Send a complete HCI command to the transport. - * - * \param pData WSF msg buffer containing an HCI command. WSF buffer ownership is released by this function. - * - * \return None. - */ -/*************************************************************************************************/ -void hciTrSendCmd(uint8_t *pData) -{ - uint16_t len; - - /* get length */ - len = pData[2] + HCI_CMD_HDR_LEN; + /* allocate LL buffer */ + if ((p = WsfMsgDataAlloc(len, HCI_TX_DATA_TAILROOM)) != NULL) + { + /* copy data */ + memcpy(p, pData, len); - /* dump event for protocol analysis */ - HCI_PDUMP_CMD(len, pData); +#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) + /* send to LL */ + LlSendAclData(p); - /* transmit ACL header and data */ - if (hciDrvWrite(HCI_CMD_TYPE, len, pData) == len) + /* free HCI buffer */ + hciCoreTxAclComplete(pContext, pData); +#endif + } + } + else { -#if CORDIO_ZERO_COPY_HCI - /* pData is not freed as the hciDrvWrite took ownership of the WSF buffer */ -#else - /* free buffer */ - WsfMsgFree(pData); -#endif // CORDIO_ZERO_COPY_HCI +#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) + /* send to LL */ + LlSendAclData(pData); + + /* LL will free HCI buffer */ + hciCoreTxAclComplete(pContext, NULL); +#endif } } - /*************************************************************************************************/ /*! - * \fn hciSerialRxIncoming - * - * \brief Receive function. Gets called by external code when bytes are received. + * \brief Send a complete HCI command to the transport. * - * \param pBuf Pointer to buffer of incoming bytes. - * \param len Number of bytes in incoming buffer. + * \param pCmdData WSF msg buffer containing an HCI command. * * \return None. */ /*************************************************************************************************/ -void hciTrSerialRxIncoming(uint8_t *pBuf, uint8_t len) +void hciTrSendCmd(uint8_t *pCmdData) { - static uint8_t stateRx = HCI_RX_STATE_IDLE; - static uint8_t pktIndRx; - static uint16_t iRx; - static uint8_t hdrRx[HCI_HDR_LEN_MAX]; - static uint8_t *pPktRx; - static uint8_t *pDataRx; - - uint8_t dataByte; - - /* loop until all bytes of incoming buffer are handled */ - while (len--) - { - /* read single byte from incoming buffer and advance to next byte */ - dataByte = *pBuf++; - - /* --- Idle State --- */ - if (stateRx == HCI_RX_STATE_IDLE) - { - /* save the packet type */ - pktIndRx = dataByte; - iRx = 0; - stateRx = HCI_RX_STATE_HEADER; - } - - /* --- Header State --- */ - else if (stateRx == HCI_RX_STATE_HEADER) - { - uint8_t hdrLen = 0; - uint16_t dataLen = 0; - - /* copy current byte into the temp header buffer */ - hdrRx[iRx++] = dataByte; - - /* determine header length based on packet type */ - switch (pktIndRx) - { - case HCI_CMD_TYPE: - hdrLen = HCI_CMD_HDR_LEN; - break; - case HCI_ACL_TYPE: - hdrLen = HCI_ACL_HDR_LEN; - break; - case HCI_EVT_TYPE: - hdrLen = HCI_EVT_HDR_LEN; - break; - default: - /* invalid packet type */ - WSF_ASSERT(0); - break; - } - - /* see if entire header has been read */ - if (iRx == hdrLen) - { - /* extract data length from header */ - switch (pktIndRx) - { - case HCI_CMD_TYPE: - dataLen = hdrRx[2]; - break; - case HCI_ACL_TYPE: - BYTES_TO_UINT16(dataLen, &hdrRx[2]); - break; - case HCI_EVT_TYPE: - dataLen = hdrRx[1]; - break; - default: - break; - } - /* allocate data buffer to hold entire packet */ - if (pktIndRx == HCI_ACL_TYPE) - { - pPktRx = (uint8_t*)WsfMsgDataAlloc(hdrLen + dataLen, 0); - } - else - { - pPktRx = (uint8_t*)WsfMsgAlloc(hdrLen + dataLen); - } - - if (pPktRx != NULL) - { - pDataRx = pPktRx; - - /* copy header into data packet (note: memcpy is not so portable) */ - { - uint8_t i; - for (i = 0; i < hdrLen; i++) - { - *pDataRx++ = hdrRx[i]; - } - } - - /* save number of bytes left to read */ - iRx = dataLen; - if (iRx == 0) - { - stateRx = HCI_RX_STATE_COMPLETE; - } - else - { - stateRx = HCI_RX_STATE_DATA; - } - } - else - { - WSF_ASSERT(0); /* allocate falied */ - } - - } - } - - /* --- Data State --- */ - else if (stateRx == HCI_RX_STATE_DATA) - { - /* write incoming byte to allocated buffer */ - *pDataRx++ = dataByte; - - /* determine if entire packet has been read */ - iRx--; - if (iRx == 0) - { - stateRx = HCI_RX_STATE_COMPLETE; - } - } - - /* --- Complete State --- */ - /* ( Note Well! There is no else-if construct by design. ) */ - if (stateRx == HCI_RX_STATE_COMPLETE) - { - /* deliver data */ - if (pPktRx != NULL) - { - hciCoreRecv(pktIndRx, pPktRx); - } - - /* reset state machine */ - stateRx = HCI_RX_STATE_IDLE; - } - } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c index 0cc0908348a..822b4081dd2 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c @@ -1,25 +1,101 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file hci_vs.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI vendor specific functions for generic controllers. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2011-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This module implements vendor-specific features for the reset sequence and vendor-specific + * HCI commands and events. */ +/*************************************************************************************************/ -#include "hci_mbed_os_adaptation.h" -#include "hci_defs.h" +#include +#include "wsf_types.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bda.h" +#include "util/bstream.h" +#include "hci_core.h" #include "hci_api.h" -#include "wsf_os.h" #include "hci_main.h" -#include "hci_core.h" +#include "hci_cmd.h" + +#if HCI_VS_TARGET == HCI_VS_GENERIC + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +static void hciCoreReadResolvingListSize(void); +static void hciCoreReadMaxDataLen(void); + +/*************************************************************************************************/ +/*! + * \fn hciCoreReadResolvingListSize + * + * \brief Read resolving list command. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciCoreReadResolvingListSize(void) +{ + /* if LL Privacy is supported by Controller and included */ + if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) && + (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY)) + { + /* send next command in sequence */ + HciLeReadResolvingListSize(); + } + else + { + hciCoreCb.resListSize = 0; + + /* send next command in sequence */ + hciCoreReadMaxDataLen(); + } +} + +/*************************************************************************************************/ +/*! + * \fn hciCoreReadMaxDataLen + * + * \brief Read maximum data length command. + * + * \return None. + */ +/*************************************************************************************************/ +static void hciCoreReadMaxDataLen(void) +{ + /* if LE Data Packet Length Extensions is supported by Controller and included */ + if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) && + (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT)) + { + /* send next command in sequence */ + HciLeReadMaxDataLen(); + } + else + { + /* send next command in sequence */ + HciLeRandCmd(); + } +} /*************************************************************************************************/ /*! @@ -32,8 +108,8 @@ /*************************************************************************************************/ void hciCoreResetStart(void) { - // forward to mbed OS - hci_mbed_os_start_reset_sequence(); + /* send an HCI Reset command to start the sequence */ + HciResetCmd(); } /*************************************************************************************************/ @@ -47,20 +123,185 @@ void hciCoreResetStart(void) * \return None. */ /*************************************************************************************************/ -void hciCoreResetSequence(uint8_t *pMsg) -{ - // forward to mbed os - hci_mbed_os_handle_reset_sequence(pMsg); -} - -void hci_mbed_os_signal_reset_sequence_done(void) +void hciCoreResetSequence(uint8_t *pMsg) { - /* last command in sequence; set resetting state and call callback */ + uint16_t opcode; wsfMsgHdr_t hdr; - hciCb.resetting = FALSE; - hdr.param = 0; - hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT; - (*hciCb.evtCback)((hciEvt_t *) &hdr); + static uint8_t randCnt; + + /* if event is a command complete event */ + if (*pMsg == HCI_CMD_CMPL_EVT) + { + /* parse parameters */ + pMsg += HCI_EVT_HDR_LEN; + pMsg++; /* skip num packets */ + BSTREAM_TO_UINT16(opcode, pMsg); + pMsg++; /* skip status */ + + /* decode opcode */ + switch (opcode) + { + case HCI_OPCODE_RESET: + /* initialize rand command count */ + randCnt = 0; + + /* send next command in sequence */ + HciSetEventMaskCmd((uint8_t *) hciEventMask); + break; + + case HCI_OPCODE_SET_EVENT_MASK: + /* send next command in sequence */ + HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask); + break; + + case HCI_OPCODE_LE_SET_EVENT_MASK: + /* send next command in sequence */ + HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2); + break; + + case HCI_OPCODE_SET_EVENT_MASK_PAGE2: + /* send next command in sequence */ + HciReadBdAddrCmd(); + break; + + case HCI_OPCODE_READ_BD_ADDR: + /* parse and store event parameters */ + BdaCpy(hciCoreCb.bdAddr, pMsg); + + /* send next command in sequence */ + HciLeReadBufSizeCmd(); + break; + + case HCI_OPCODE_LE_READ_BUF_SIZE: + /* parse and store event parameters */ + BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg); + BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg); + + /* initialize ACL buffer accounting */ + hciCoreCb.availBufs = hciCoreCb.numBufs; + + /* send next command in sequence */ + HciLeReadSupStatesCmd(); + break; + + case HCI_OPCODE_LE_READ_SUP_STATES: + /* parse and store event parameters */ + memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN); + + /* send next command in sequence */ + HciLeReadWhiteListSizeCmd(); + break; + + case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: + /* parse and store event parameters */ + BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg); + + /* send next command in sequence */ + HciLeReadLocalSupFeatCmd(); + break; + + case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT: + /* parse and store event parameters */ + BSTREAM_TO_UINT64(hciCoreCb.leSupFeat, pMsg); + + /* if Isochronous Channels (Host support) is supported and included */ + if (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT) + { + HciLeSetHostFeatureCmd(HCI_LE_FEAT_BIT_ISO_HOST_SUPPORT, TRUE); + break; + } + /* Fallthrough */ + + case HCI_OPCODE_LE_SET_HOST_FEATURE: + /* send next command in sequence */ + hciCoreReadResolvingListSize(); + break; + + case HCI_OPCODE_LE_READ_RES_LIST_SIZE: + /* parse and store event parameters */ + BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg); + + /* send next command in sequence */ + hciCoreReadMaxDataLen(); + break; + + case HCI_OPCODE_LE_READ_MAX_DATA_LEN: + { + uint16_t maxTxOctets; + uint16_t maxTxTime; + + BSTREAM_TO_UINT16(maxTxOctets, pMsg); + BSTREAM_TO_UINT16(maxTxTime, pMsg); + + /* use Controller's maximum supported payload octets and packet duration times + * for transmission as Host's suggested values for maximum transmission number + * of payload octets and maximum packet transmission time for new connections. + */ + HciLeWriteDefDataLen(maxTxOctets, maxTxTime); + } + break; + + case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN: + /* send next command in sequence */ + HciReadLocalVerInfoCmd(); + break; + + case HCI_OPCODE_READ_LOCAL_VER_INFO: + /* parse and store event parameters */ + BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.hciVersion, pMsg); + BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.hciRevision, pMsg); + BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.lmpVersion, pMsg); + BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.manufacturerName, pMsg); + BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.lmpSubversion, pMsg); + + if (hciCoreCb.extResetSeq) + { + /* send first extended command */ + (*hciCoreCb.extResetSeq)(pMsg, opcode); + } + else + { + /* initialize extended parameters */ + hciCoreCb.maxAdvDataLen = 0; + hciCoreCb.numSupAdvSets = 0; + hciCoreCb.perAdvListSize = 0; + + /* send next command in sequence */ + HciLeRandCmd(); + } + break; + + case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN: + case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS: + case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE: + if (hciCoreCb.extResetSeq) + { + /* send next extended command in sequence */ + (*hciCoreCb.extResetSeq)(pMsg, opcode); + } + break; + + case HCI_OPCODE_LE_RAND: + /* check if need to send second rand command */ + if (randCnt < (HCI_RESET_RAND_CNT-1)) + { + randCnt++; + HciLeRandCmd(); + } + else + { + /* last command in sequence; set resetting state and call callback */ + hciCb.resetting = FALSE; + hdr.param = 0; + hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT; + (*hciCb.evtCback)((hciEvt_t *) &hdr); + } + break; + + default: + break; + } + } } /*************************************************************************************************/ @@ -129,3 +370,5 @@ void HciVsInit(uint8_t param) { hciCoreCb.extResetSeq = NULL; } + +#endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c index 4f3c15dd103..0152f93bc3c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c @@ -1,26 +1,36 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_cs.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Software foundation OS main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ +/*************************************************************************************************/ -#ifdef __IAR_SYSTEMS_ICC__ -#include -#endif #include "wsf_types.h" #include "wsf_cs.h" + #include "wsf_assert.h" -#include "wsf_mbed_os_adaptation.h" +#include "pal_sys.h" + +#if (WSF_CS_STATS == TRUE) +#include "pal_bb.h" +#endif /************************************************************************************************** Global Variables @@ -31,12 +41,6 @@ uint8_t wsfCsNesting = 0; #if (WSF_CS_STATS == TRUE) -/*! \brief Critical section entrance callback. */ -WsfCsTimestamp_t wsfCsTimestampCback = NULL; - -/*! \brief Critical section exit callback. */ -WsfCsTimebase_t wsfCsTimebaseCback = NULL; - /*! \brief Critical section start time. */ static uint32_t wsfCsStatsStartTime = 0; @@ -62,48 +66,21 @@ uint32_t WsfCsStatsGetCsWaterMark(void) return wsfCsStatsWatermarkUsec; } -/*************************************************************************************************/ -/*! - * \brief Register critical section statistics hooks. - * - * \param timestampCback Callback for obtaining the current timestamp. - * \param timebaseCback Callback for converting timestamp delta into microseconds. - * - * \return None. - */ -/*************************************************************************************************/ -void WsfCsStatsRegister(WsfCsTimestamp_t timestampCback, WsfCsTimebase_t timebaseCback) -{ - WSF_ASSERT(timestampCback != NULL); - WSF_ASSERT(timebaseCback != NULL); - - wsfCsTimestampCback = timestampCback; - wsfCsTimebaseCback = timebaseCback; - wsfCsStatsWatermarkUsec = 0; -} - /*************************************************************************************************/ /*! * \brief Mark the beginning of a CS. - * - * \return None. */ /*************************************************************************************************/ static void wsfCsStatsEnter(void) { /* N.B. Code path must not use critical sections. */ - if (wsfCsTimestampCback) - { - wsfCsStatsStartTimeValid = wsfCsTimestampCback(&wsfCsStatsStartTime); - } + wsfCsStatsStartTimeValid = PalBbGetTimestamp(&wsfCsStatsStartTime); } /*************************************************************************************************/ /*! * \brief Record the CS watermark. - * - * \return None. */ /*************************************************************************************************/ static void wsfCsStatsExit(void) @@ -115,15 +92,11 @@ static void wsfCsStatsExit(void) return; } - /* Valid wsfCsStatsStartTimeValid assumes valid WsfCsStatsRegister(). */ - WSF_ASSERT(wsfCsTimestampCback != NULL); - WSF_ASSERT(wsfCsTimebaseCback != NULL); - uint32_t exitTime; - if (wsfCsTimestampCback(&exitTime)) + if (PalBbGetTimestamp(&exitTime)) { - uint32_t durUsec = wsfCsTimebaseCback(exitTime - wsfCsStatsStartTime); + uint32_t durUsec = exitTime - wsfCsStatsStartTime; if (durUsec > wsfCsStatsWatermarkUsec) { wsfCsStatsWatermarkUsec = durUsec; @@ -136,23 +109,37 @@ static void wsfCsStatsExit(void) /*************************************************************************************************/ /*! * \brief Enter a critical section. - * - * \return None. */ /*************************************************************************************************/ void WsfCsEnter(void) { - wsf_mbed_os_critical_section_enter(); + if (wsfCsNesting == 0) + { + PalEnterCs(); + +#if (WSF_CS_STATS == TRUE) + wsfCsStatsEnter(); +#endif + } + wsfCsNesting++; } /*************************************************************************************************/ /*! - * \brief Enter a critical section. - * - * \return None. + * \brief Exit a critical section. */ /*************************************************************************************************/ void WsfCsExit(void) { - wsf_mbed_os_critical_section_exit(); + WSF_ASSERT(wsfCsNesting != 0); + + wsfCsNesting--; + if (wsfCsNesting == 0) + { +#if (WSF_CS_STATS == TRUE) + wsfCsStatsExit(); +#endif + + PalExitCs(); + } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c index 0f2640d7626..84f1d0f4b1f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c @@ -1,18 +1,26 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file wsf_os.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Software foundation OS main module. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ +/*************************************************************************************************/ #ifdef __IAR_SYSTEMS_ICC__ #include @@ -27,7 +35,10 @@ #include "wsf_buf.h" #include "wsf_msg.h" #include "wsf_cs.h" -#include "wsf_mbed_os_adaptation.h" + +#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) +#include "cmsis_os2.h" +#endif /************************************************************************************************** Compile time assert checks @@ -43,15 +54,23 @@ WSF_CT_ASSERT(sizeof(uint32_t) == 4); /* maximum number of event handlers per task */ #ifndef WSF_MAX_HANDLERS -#define WSF_MAX_HANDLERS 16 +#define WSF_MAX_HANDLERS 16 #endif #if WSF_OS_DIAG == TRUE -#define WSF_OS_SET_ACTIVE_HANDLER_ID(id) WsfActiveHandler = id; +#define WSF_OS_SET_ACTIVE_HANDLER_ID(id) (WsfActiveHandler = id); #else #define WSF_OS_SET_ACTIVE_HANDLER_ID(id) #endif /* WSF_OS_DIAG */ +#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) +/*! \brief Thread sleep flag */ +#define WSF_OS_THREAD_SLEEP_WAKEUP_FLAG 0x0001 +#endif + +/*! \brief OS serivice function number */ +#define WSF_OS_MAX_SERVICE_FUNCTIONS 3 + /************************************************************************************************** Data Types **************************************************************************************************/ @@ -69,7 +88,9 @@ typedef struct /*! \brief OS structure */ typedef struct { - wsfOsTask_t task; + wsfOsTask_t task; + WsfOsIdleCheckFunc_t sleepCheckFuncs[WSF_OS_MAX_SERVICE_FUNCTIONS]; + uint8_t numFunc; } wsfOs_t; /************************************************************************************************** @@ -84,11 +105,13 @@ wsfOs_t wsfOs; wsfHandlerId_t WsfActiveHandler; #endif /* WSF_OS_DIAG */ +#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) +static osThreadId_t wsfOsThreadId; +#endif + /*************************************************************************************************/ /*! * \brief Lock task scheduling. - * - * \return None. */ /*************************************************************************************************/ void WsfTaskLock(void) @@ -99,8 +122,6 @@ void WsfTaskLock(void) /*************************************************************************************************/ /*! * \brief Unock task scheduling. - * - * \return None. */ /*************************************************************************************************/ void WsfTaskUnlock(void) @@ -114,14 +135,12 @@ void WsfTaskUnlock(void) * * \param handlerId Handler ID. * \param event Event or events to set. - * - * \return None. */ /*************************************************************************************************/ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event) { WSF_CS_INIT(cs); - // coverity[CONSTANT_EXPRESSION_RESULT] + WSF_ASSERT(WSF_HANDLER_FROM_ID(handlerId) < WSF_MAX_HANDLERS); WSF_TRACE_INFO2("WsfSetEvent handlerId:%u event:%u", handlerId, event); @@ -132,7 +151,6 @@ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event) WSF_CS_EXIT(cs); /* set event in OS */ - wsf_mbed_ble_signal_event(); } /*************************************************************************************************/ @@ -141,8 +159,6 @@ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event) * * \param handlerId Event handler ID. * \param event Task event mask. - * - * \return None. */ /*************************************************************************************************/ void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event) @@ -157,7 +173,6 @@ void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event) WSF_CS_EXIT(cs); /* set event in OS */ - wsf_mbed_ble_signal_event(); } /*************************************************************************************************/ @@ -221,13 +236,15 @@ bool_t wsfOsReadyToSleep(void) void WsfOsInit(void) { memset(&wsfOs, 0, sizeof(wsfOs)); + +#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) + osKernelInitialize(); /* Initialize CMSIS-RTOS. */ +#endif } /*************************************************************************************************/ /*! * \brief Event dispatched. Designed to be called repeatedly from infinite loop. - * - * \return None. */ /*************************************************************************************************/ void wsfOsDispatcher(void) @@ -291,3 +308,100 @@ void wsfOsDispatcher(void) } } } + +#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) +/*************************************************************************************************/ +/*! + * \brief Idle thread. + * + * \param pArg Pointer to argument. + */ +/*************************************************************************************************/ +void osRtxIdleThread(void *pArg) +{ + bool_t activeFlag = FALSE; + + (void) pArg; + + while(TRUE) + { + activeFlag = FALSE; + + for (unsigned int i = 0; i < wsfOs.numFunc; i++) + { + if (wsfOs.sleepCheckFuncs[i]) + { + activeFlag |= wsfOs.sleepCheckFuncs[i](); + } + } + + if (!activeFlag) + { + WsfTimerSleep(); + } + osThreadFlagsSet(wsfOsThreadId, WSF_OS_THREAD_SLEEP_WAKEUP_FLAG); + } +} + +/*************************************************************************************************/ +/*! + * \brief Main thread. + * + * \param pArg Pointer to argument. + */ +/*************************************************************************************************/ +void wsfThread(void *pArg) +{ + (void) pArg; + + while(TRUE) + { + WsfTimerSleepUpdate(); + wsfOsDispatcher(); + osThreadFlagsWait(WSF_OS_THREAD_SLEEP_WAKEUP_FLAG, osFlagsWaitAny ,osWaitForever); + } +} +#endif + +/*************************************************************************************************/ +/*! + * \brief Register service check functions. + * + * \param func Service function. + */ +/*************************************************************************************************/ +void WsfOsRegisterSleepCheckFunc(WsfOsIdleCheckFunc_t func) +{ + wsfOs.sleepCheckFuncs[wsfOs.numFunc++] = func; +} + +/*************************************************************************************************/ +/*! + * \brief OS starts main loop + */ +/*************************************************************************************************/ +void WsfOsEnterMainLoop(void) +{ + bool_t activeFlag = FALSE; + + while (TRUE) + { + WsfTimerSleepUpdate(); + wsfOsDispatcher(); + + activeFlag = FALSE; + + for (unsigned int i = 0; i < wsfOs.numFunc; i++) + { + if (wsfOs.sleepCheckFuncs[i]) + { + activeFlag |= wsfOs.sleepCheckFuncs[i](); + } + } + + if (!activeFlag) + { + WsfTimerSleep(); + } + } +} From fc59443a092201f17fad778e0316840274a68ed5 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 5 Jun 2020 16:50:42 +0100 Subject: [PATCH 02/38] hciDrvWrite no longer needed --- .../TARGET_CORDIO/stack_adaptation/hci_drv.c | 23 ------------------- .../stack_adaptation/hci_mbed_os_adaptation.h | 1 - 2 files changed, 24 deletions(-) delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_drv.c diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_drv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_drv.c deleted file mode 100644 index 0b7df1b2d50..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_drv.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2009-2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "hci_mbed_os_adaptation.h" - -uint16_t hciDrvWrite(uint8_t type, uint16_t len, uint8_t *pData) -{ - // forward write to mbed os. - return hci_mbed_os_drv_write(type, len, pData); -} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_mbed_os_adaptation.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_mbed_os_adaptation.h index a0e9ea4cf6c..843f479a040 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_mbed_os_adaptation.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_mbed_os_adaptation.h @@ -33,7 +33,6 @@ extern "C" { * * @note type parameter allows the driver layer to prepend the data with a * header on the same write transaction. - * @note mbed os wrapper of hciDrvWrite */ uint16_t hci_mbed_os_drv_write(uint8_t type, uint16_t len, uint8_t *pData); From bb4b58b2398e8bed30b1048c22e7c8f5f0298c1d Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:22:42 +0100 Subject: [PATCH 03/38] porting adaptation layer --- .../TARGET_CORDIO/stack_adaptation/hci_tr.c | 233 +++++++++++++--- .../TARGET_CORDIO/stack_adaptation/hci_vs.c | 262 ++---------------- .../TARGET_CORDIO/stack_adaptation/wsf_cs.c | 103 +------ .../TARGET_CORDIO/stack_adaptation/wsf_os.c | 52 +--- 4 files changed, 226 insertions(+), 424 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c index 412177d965a..9245499fa19 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_tr.c @@ -25,14 +25,28 @@ #include #include "wsf_types.h" #include "wsf_msg.h" +#include "wsf_assert.h" #include "util/bstream.h" #include "hci_api.h" #include "hci_core.h" #include "hci_tr.h" +#include "hci_drv.h" -#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) -#include "ll_api.h" -#endif +/* PORTING: EXACTLE removed as replaced by zero copy hci driver in mbedos */ + +uint16_t hci_mbed_os_drv_write(uint8_t type, uint16_t len, uint8_t *pData); + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +typedef enum +{ + HCI_RX_STATE_IDLE, + HCI_RX_STATE_HEADER, + HCI_RX_STATE_DATA, + HCI_RX_STATE_COMPLETE +} hciRxState_t; /*************************************************************************************************/ /*! @@ -48,40 +62,22 @@ /*************************************************************************************************/ void hciTrSendAclData(void *pContext, uint8_t *pData) { + /* PORTING: sending and fragmenting done by mbed-os */ uint16_t len; - uint8_t *p; - /* if fragmenting */ - if (hciCoreTxAclDataFragmented(pContext)) - { - /* get 16-bit length */ - BYTES_TO_UINT16(len, (pData + 2)) - len += HCI_ACL_HDR_LEN; - - /* allocate LL buffer */ - if ((p = WsfMsgDataAlloc(len, HCI_TX_DATA_TAILROOM)) != NULL) - { - /* copy data */ - memcpy(p, pData, len); + /* get 16-bit length */ + BYTES_TO_UINT16(len, (pData + 2)) + len += HCI_ACL_HDR_LEN; -#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) - /* send to LL */ - LlSendAclData(p); - - /* free HCI buffer */ - hciCoreTxAclComplete(pContext, pData); -#endif - } - } - else + /* transmit ACL header and data */ + if (hci_mbed_os_drv_write(HCI_ACL_TYPE, len, pData) == len) { -#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1) - /* send to LL */ - LlSendAclData(pData); - - /* LL will free HCI buffer */ - hciCoreTxAclComplete(pContext, NULL); -#endif +#if CORDIO_ZERO_COPY_HCI + /* pData is not freed as the hci_mbed_os_drv_write took ownership of the WSF buffer */ +#else + /* free buffer */ + hciCoreTxAclComplete((hciCoreConn_t *)pContext, pData); +#endif // CORDIO_ZERO_COPY_HCI } } @@ -96,5 +92,176 @@ void hciTrSendAclData(void *pContext, uint8_t *pData) /*************************************************************************************************/ void hciTrSendCmd(uint8_t *pCmdData) { + /* PORTING: sending done by mbed-os */ + uint16_t len; + + /* get length */ + len = pCmdData[2] + HCI_CMD_HDR_LEN; + + /* transmit ACL header and data */ + if (hci_mbed_os_drv_write(HCI_CMD_TYPE, len, pCmdData) == len) + { +#if CORDIO_ZERO_COPY_HCI + /* pData is not freed as the hci_mbed_os_drv_write took ownership of the WSF buffer */ +#else + /* free buffer */ + WsfMsgFree(pCmdData); +#endif // CORDIO_ZERO_COPY_HCI + } +} + +/*************************************************************************************************/ +/*! + * \fn hciSerialRxIncoming + * + * \brief Receive function. Gets called by external code when bytes are received. + * + * \param pBuf Pointer to buffer of incoming bytes. + * \param len Number of bytes in incoming buffer. + * + * \return None. + */ +/*************************************************************************************************/ +void hciTrSerialRxIncoming(uint8_t *pBuf, uint8_t len) +{ + static uint8_t stateRx = HCI_RX_STATE_IDLE; + static uint8_t pktIndRx; + static uint16_t iRx; + static uint8_t hdrRx[HCI_ACL_HDR_LEN]; + static uint8_t *pPktRx; + static uint8_t *pDataRx; + uint8_t dataByte; + + /* loop until all bytes of incoming buffer are handled */ + while (len--) + { + /* read single byte from incoming buffer and advance to next byte */ + dataByte = *pBuf++; + + /* --- Idle State --- */ + if (stateRx == HCI_RX_STATE_IDLE) + { + /* save the packet type */ + pktIndRx = dataByte; + iRx = 0; + stateRx = HCI_RX_STATE_HEADER; + } + + /* --- Header State --- */ + else if (stateRx == HCI_RX_STATE_HEADER) + { + uint8_t hdrLen = 0; + uint16_t dataLen = 0; + + /* copy current byte into the temp header buffer */ + hdrRx[iRx++] = dataByte; + + /* determine header length based on packet type */ + switch (pktIndRx) + { + case HCI_CMD_TYPE: + hdrLen = HCI_CMD_HDR_LEN; + break; + case HCI_ACL_TYPE: + hdrLen = HCI_ACL_HDR_LEN; + break; + case HCI_EVT_TYPE: + hdrLen = HCI_EVT_HDR_LEN; + break; + default: + /* invalid packet type */ + WSF_ASSERT(0); + break; + } + + /* see if entire header has been read */ + if (iRx == hdrLen) + { + /* extract data length from header */ + switch (pktIndRx) + { + case HCI_CMD_TYPE: + dataLen = hdrRx[2]; + break; + case HCI_ACL_TYPE: + BYTES_TO_UINT16(dataLen, &hdrRx[2]); + break; + case HCI_EVT_TYPE: + dataLen = hdrRx[1]; + break; + default: + break; + } + + /* allocate data buffer to hold entire packet */ + if (pktIndRx == HCI_ACL_TYPE) + { + pPktRx = (uint8_t*)WsfMsgDataAlloc(hdrLen + dataLen, 0); + } + else + { + pPktRx = (uint8_t*)WsfMsgAlloc(hdrLen + dataLen); + } + + if (pPktRx != NULL) + { + pDataRx = pPktRx; + + /* copy header into data packet (note: memcpy is not so portable) */ + { + uint8_t i; + for (i = 0; i < hdrLen; i++) + { + *pDataRx++ = hdrRx[i]; + } + } + + /* save number of bytes left to read */ + iRx = dataLen; + if (iRx == 0) + { + stateRx = HCI_RX_STATE_COMPLETE; + } + else + { + stateRx = HCI_RX_STATE_DATA; + } + } + else + { + WSF_ASSERT(0); /* allocate falied */ + } + + } + } + + /* --- Data State --- */ + else if (stateRx == HCI_RX_STATE_DATA) + { + /* write incoming byte to allocated buffer */ + *pDataRx++ = dataByte; + + /* determine if entire packet has been read */ + iRx--; + if (iRx == 0) + { + stateRx = HCI_RX_STATE_COMPLETE; + } + } + + /* --- Complete State --- */ + /* ( Note Well! There is no else-if construct by design. ) */ + if (stateRx == HCI_RX_STATE_COMPLETE) + { + /* deliver data */ + if (pPktRx != NULL) + { + hciCoreRecv(pktIndRx, pPktRx); + } + + /* reset state machine */ + stateRx = HCI_RX_STATE_IDLE; + } + } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c index 822b4081dd2..42b39617981 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/hci_vs.c @@ -25,77 +25,14 @@ */ /*************************************************************************************************/ -#include -#include "wsf_types.h" -#include "wsf_msg.h" -#include "wsf_trace.h" -#include "util/bda.h" -#include "util/bstream.h" #include "hci_core.h" #include "hci_api.h" #include "hci_main.h" #include "hci_cmd.h" -#if HCI_VS_TARGET == HCI_VS_GENERIC +#include "hci_mbed_os_adaptation.h" -/************************************************************************************************** - Local Functions -**************************************************************************************************/ - -static void hciCoreReadResolvingListSize(void); -static void hciCoreReadMaxDataLen(void); - -/*************************************************************************************************/ -/*! - * \fn hciCoreReadResolvingListSize - * - * \brief Read resolving list command. - * - * \return None. - */ -/*************************************************************************************************/ -static void hciCoreReadResolvingListSize(void) -{ - /* if LL Privacy is supported by Controller and included */ - if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) && - (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY)) - { - /* send next command in sequence */ - HciLeReadResolvingListSize(); - } - else - { - hciCoreCb.resListSize = 0; - - /* send next command in sequence */ - hciCoreReadMaxDataLen(); - } -} - -/*************************************************************************************************/ -/*! - * \fn hciCoreReadMaxDataLen - * - * \brief Read maximum data length command. - * - * \return None. - */ -/*************************************************************************************************/ -static void hciCoreReadMaxDataLen(void) -{ - /* if LE Data Packet Length Extensions is supported by Controller and included */ - if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) && - (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT)) - { - /* send next command in sequence */ - HciLeReadMaxDataLen(); - } - else - { - /* send next command in sequence */ - HciLeRandCmd(); - } -} +/* PORTING: reset handling code has been removed since it's handled by the mbed-os driver */ /*************************************************************************************************/ /*! @@ -108,8 +45,8 @@ static void hciCoreReadMaxDataLen(void) /*************************************************************************************************/ void hciCoreResetStart(void) { - /* send an HCI Reset command to start the sequence */ - HciResetCmd(); + /* PORTING: reset sequence handled by mbed-os */ + hci_mbed_os_start_reset_sequence(); } /*************************************************************************************************/ @@ -123,185 +60,20 @@ void hciCoreResetStart(void) * \return None. */ /*************************************************************************************************/ -void hciCoreResetSequence(uint8_t *pMsg) +void hciCoreResetSequence(uint8_t *pMsg) +{ + /* PORTING: reset sequence handled by mbed-os */ + hci_mbed_os_handle_reset_sequence(pMsg); +} + +void hci_mbed_os_signal_reset_sequence_done(void) { - uint16_t opcode; + /* last command in sequence; set resetting state and call callback */ wsfMsgHdr_t hdr; - static uint8_t randCnt; - - /* if event is a command complete event */ - if (*pMsg == HCI_CMD_CMPL_EVT) - { - /* parse parameters */ - pMsg += HCI_EVT_HDR_LEN; - pMsg++; /* skip num packets */ - BSTREAM_TO_UINT16(opcode, pMsg); - pMsg++; /* skip status */ - - /* decode opcode */ - switch (opcode) - { - case HCI_OPCODE_RESET: - /* initialize rand command count */ - randCnt = 0; - - /* send next command in sequence */ - HciSetEventMaskCmd((uint8_t *) hciEventMask); - break; - - case HCI_OPCODE_SET_EVENT_MASK: - /* send next command in sequence */ - HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask); - break; - - case HCI_OPCODE_LE_SET_EVENT_MASK: - /* send next command in sequence */ - HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2); - break; - - case HCI_OPCODE_SET_EVENT_MASK_PAGE2: - /* send next command in sequence */ - HciReadBdAddrCmd(); - break; - - case HCI_OPCODE_READ_BD_ADDR: - /* parse and store event parameters */ - BdaCpy(hciCoreCb.bdAddr, pMsg); - - /* send next command in sequence */ - HciLeReadBufSizeCmd(); - break; - - case HCI_OPCODE_LE_READ_BUF_SIZE: - /* parse and store event parameters */ - BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg); - BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg); - - /* initialize ACL buffer accounting */ - hciCoreCb.availBufs = hciCoreCb.numBufs; - - /* send next command in sequence */ - HciLeReadSupStatesCmd(); - break; - - case HCI_OPCODE_LE_READ_SUP_STATES: - /* parse and store event parameters */ - memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN); - - /* send next command in sequence */ - HciLeReadWhiteListSizeCmd(); - break; - - case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: - /* parse and store event parameters */ - BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg); - - /* send next command in sequence */ - HciLeReadLocalSupFeatCmd(); - break; - - case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT: - /* parse and store event parameters */ - BSTREAM_TO_UINT64(hciCoreCb.leSupFeat, pMsg); - - /* if Isochronous Channels (Host support) is supported and included */ - if (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT) - { - HciLeSetHostFeatureCmd(HCI_LE_FEAT_BIT_ISO_HOST_SUPPORT, TRUE); - break; - } - /* Fallthrough */ - - case HCI_OPCODE_LE_SET_HOST_FEATURE: - /* send next command in sequence */ - hciCoreReadResolvingListSize(); - break; - - case HCI_OPCODE_LE_READ_RES_LIST_SIZE: - /* parse and store event parameters */ - BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg); - - /* send next command in sequence */ - hciCoreReadMaxDataLen(); - break; - - case HCI_OPCODE_LE_READ_MAX_DATA_LEN: - { - uint16_t maxTxOctets; - uint16_t maxTxTime; - - BSTREAM_TO_UINT16(maxTxOctets, pMsg); - BSTREAM_TO_UINT16(maxTxTime, pMsg); - - /* use Controller's maximum supported payload octets and packet duration times - * for transmission as Host's suggested values for maximum transmission number - * of payload octets and maximum packet transmission time for new connections. - */ - HciLeWriteDefDataLen(maxTxOctets, maxTxTime); - } - break; - - case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN: - /* send next command in sequence */ - HciReadLocalVerInfoCmd(); - break; - - case HCI_OPCODE_READ_LOCAL_VER_INFO: - /* parse and store event parameters */ - BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.hciVersion, pMsg); - BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.hciRevision, pMsg); - BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.lmpVersion, pMsg); - BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.manufacturerName, pMsg); - BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.lmpSubversion, pMsg); - - if (hciCoreCb.extResetSeq) - { - /* send first extended command */ - (*hciCoreCb.extResetSeq)(pMsg, opcode); - } - else - { - /* initialize extended parameters */ - hciCoreCb.maxAdvDataLen = 0; - hciCoreCb.numSupAdvSets = 0; - hciCoreCb.perAdvListSize = 0; - - /* send next command in sequence */ - HciLeRandCmd(); - } - break; - - case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN: - case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS: - case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE: - if (hciCoreCb.extResetSeq) - { - /* send next extended command in sequence */ - (*hciCoreCb.extResetSeq)(pMsg, opcode); - } - break; - - case HCI_OPCODE_LE_RAND: - /* check if need to send second rand command */ - if (randCnt < (HCI_RESET_RAND_CNT-1)) - { - randCnt++; - HciLeRandCmd(); - } - else - { - /* last command in sequence; set resetting state and call callback */ - hciCb.resetting = FALSE; - hdr.param = 0; - hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT; - (*hciCb.evtCback)((hciEvt_t *) &hdr); - } - break; - - default: - break; - } - } + hciCb.resetting = FALSE; + hdr.param = 0; + hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT; + (*hciCb.evtCback)((hciEvt_t *) &hdr); } /*************************************************************************************************/ @@ -370,5 +142,3 @@ void HciVsInit(uint8_t param) { hciCoreCb.extResetSeq = NULL; } - -#endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c index 0152f93bc3c..9f33e6f54ab 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_cs.c @@ -25,86 +25,9 @@ #include "wsf_types.h" #include "wsf_cs.h" -#include "wsf_assert.h" -#include "pal_sys.h" +#include "wsf_mbed_os_adaptation.h" -#if (WSF_CS_STATS == TRUE) -#include "pal_bb.h" -#endif - -/************************************************************************************************** - Global Variables -**************************************************************************************************/ - -/*! \brief Critical section nesting level. */ -uint8_t wsfCsNesting = 0; - -#if (WSF_CS_STATS == TRUE) - -/*! \brief Critical section start time. */ -static uint32_t wsfCsStatsStartTime = 0; - -/*! \brief Critical section start time valid. */ -static bool_t wsfCsStatsStartTimeValid = FALSE; - -/*! \brief Critical section duration watermark level. */ -uint16_t wsfCsStatsWatermarkUsec = 0; - -#endif - -#if (WSF_CS_STATS == TRUE) - -/*************************************************************************************************/ -/*! - * \brief Get critical section duration watermark level. - * - * \return Critical section duration watermark level. - */ -/*************************************************************************************************/ -uint32_t WsfCsStatsGetCsWaterMark(void) -{ - return wsfCsStatsWatermarkUsec; -} - -/*************************************************************************************************/ -/*! - * \brief Mark the beginning of a CS. - */ -/*************************************************************************************************/ -static void wsfCsStatsEnter(void) -{ - /* N.B. Code path must not use critical sections. */ - - wsfCsStatsStartTimeValid = PalBbGetTimestamp(&wsfCsStatsStartTime); -} - -/*************************************************************************************************/ -/*! - * \brief Record the CS watermark. - */ -/*************************************************************************************************/ -static void wsfCsStatsExit(void) -{ - /* N.B. Code path must not use critical sections. */ - - if (wsfCsStatsStartTimeValid != TRUE) - { - return; - } - - uint32_t exitTime; - - if (PalBbGetTimestamp(&exitTime)) - { - uint32_t durUsec = exitTime - wsfCsStatsStartTime; - if (durUsec > wsfCsStatsWatermarkUsec) - { - wsfCsStatsWatermarkUsec = durUsec; - } - } -} - -#endif +/* PORTING: WSF_CS_STATS are removed and critical section is handled by mbed-os */ /*************************************************************************************************/ /*! @@ -113,15 +36,7 @@ static void wsfCsStatsExit(void) /*************************************************************************************************/ void WsfCsEnter(void) { - if (wsfCsNesting == 0) - { - PalEnterCs(); - -#if (WSF_CS_STATS == TRUE) - wsfCsStatsEnter(); -#endif - } - wsfCsNesting++; + wsf_mbed_os_critical_section_enter(); } /*************************************************************************************************/ @@ -131,15 +46,5 @@ void WsfCsEnter(void) /*************************************************************************************************/ void WsfCsExit(void) { - WSF_ASSERT(wsfCsNesting != 0); - - wsfCsNesting--; - if (wsfCsNesting == 0) - { -#if (WSF_CS_STATS == TRUE) - wsfCsStatsExit(); -#endif - - PalExitCs(); - } + wsf_mbed_os_critical_section_exit(); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c index 84f1d0f4b1f..cfbe758f7f3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/wsf_os.c @@ -36,6 +36,8 @@ #include "wsf_msg.h" #include "wsf_cs.h" +#include "wsf_mbed_os_adaptation.h" + #if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1) #include "cmsis_os2.h" #endif @@ -68,9 +70,6 @@ WSF_CT_ASSERT(sizeof(uint32_t) == 4); #define WSF_OS_THREAD_SLEEP_WAKEUP_FLAG 0x0001 #endif -/*! \brief OS serivice function number */ -#define WSF_OS_MAX_SERVICE_FUNCTIONS 3 - /************************************************************************************************** Data Types **************************************************************************************************/ @@ -89,8 +88,7 @@ typedef struct typedef struct { wsfOsTask_t task; - WsfOsIdleCheckFunc_t sleepCheckFuncs[WSF_OS_MAX_SERVICE_FUNCTIONS]; - uint8_t numFunc; + /* PORTING: sleep checking funcs removed as not needed as handled by mbedos */ } wsfOs_t; /************************************************************************************************** @@ -151,6 +149,7 @@ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event) WSF_CS_EXIT(cs); /* set event in OS */ + wsf_mbed_ble_signal_event(); } /*************************************************************************************************/ @@ -173,6 +172,7 @@ void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event) WSF_CS_EXIT(cs); /* set event in OS */ + wsf_mbed_ble_signal_event(); } /*************************************************************************************************/ @@ -363,45 +363,5 @@ void wsfThread(void *pArg) } #endif -/*************************************************************************************************/ -/*! - * \brief Register service check functions. - * - * \param func Service function. - */ -/*************************************************************************************************/ -void WsfOsRegisterSleepCheckFunc(WsfOsIdleCheckFunc_t func) -{ - wsfOs.sleepCheckFuncs[wsfOs.numFunc++] = func; -} - -/*************************************************************************************************/ -/*! - * \brief OS starts main loop - */ -/*************************************************************************************************/ -void WsfOsEnterMainLoop(void) -{ - bool_t activeFlag = FALSE; - - while (TRUE) - { - WsfTimerSleepUpdate(); - wsfOsDispatcher(); - - activeFlag = FALSE; - - for (unsigned int i = 0; i < wsfOs.numFunc; i++) - { - if (wsfOs.sleepCheckFuncs[i]) - { - activeFlag |= wsfOs.sleepCheckFuncs[i](); - } - } +/* PORTING: main loop and sleep are redundant as the they are handled by mbedos */ - if (!activeFlag) - { - WsfTimerSleep(); - } - } -} From 764f18c4bd427d19a2d6b86dbdf3dc8dcd196a6b Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:24:41 +0100 Subject: [PATCH 04/38] add crit section to cordio stack pal --- .../stack_adaptation/pal_mbed_os_adaptation.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp index 62d9b343767..39723a3af26 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp @@ -19,6 +19,7 @@ #include "stack/platform/include/pal_uart.h" #include "stack/platform/include/pal_nvm.h" #include "hal/ticker_api.h" +#include "mbed_critical.h" #ifdef __cplusplus extern "C" { @@ -141,6 +142,17 @@ MBED_WEAK void PalSysSleep() MBED_ERROR(function_not_implemented, "Provide implementation of PalSysSleep"); } +/* CS */ + +MBED_WEAK void PalEnterCs(void) +{ + core_util_critical_section_enter(); +} +MBED_WEAK void PalExitCs(void) +{ + core_util_critical_section_exit(); +} + #ifdef __cplusplus }; #endif From 313651bb2ee110cfb6e482f5b4c6133865c96aa7 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:25:00 +0100 Subject: [PATCH 05/38] remove nvm --- .../TARGET_CORDIO/stack/wsf/include/wsf_nvm.h | 125 ------ .../wsf/sources/port/baremetal/wsf_nvm.c | 411 ------------------ .../pal_mbed_os_adaptation.cpp | 29 -- 3 files changed, 565 deletions(-) delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_nvm.h delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_nvm.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_nvm.h deleted file mode 100644 index f058f0bc774..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_nvm.h +++ /dev/null @@ -1,125 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file wsf_nvm.h - * - * \brief NVM service. - * - * Copyright (c) 2019 Arm Ltd. All Rights Reserved. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ -#ifndef WSF_NVM_H -#define WSF_NVM_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*! \addtogroup WSF_NVM_API - * \{ */ - -/*! \brief Operation completion callback. */ -typedef void (*WsfNvmCompEvent_t)(bool_t status); - -/************************************************************************************************** - Function Declarations -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Read data. - * - * \param charId charactor arrary for NVM ID. - * - * \return if Read NVM successfully. - */ -/*************************************************************************************************/ -static inline uint64_t WsfNvmConvertChar8to64Bit(char *charId) -{ - uint64_t retValue = 0; - - for (uint8_t i = 0; i < 8; i++) - { - retValue |= ((uint64_t)charId[7 - i]) << (8*i); - } - return retValue; -} - -/*************************************************************************************************/ -/*! - * \brief Initialize the WSF NVM. - */ -/*************************************************************************************************/ -void WsfNvmInit(void); - -/*************************************************************************************************/ -/*! - * \brief Read data. - * - * \param id Read ID. - * \param pData Buffer to read to. - * \param len Data length to read. - * \param compCback Read callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmReadData(uint64_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback); - -/*************************************************************************************************/ -/*! - * \brief Write data. - * - * \param id Write ID. - * \param pData Buffer to write. - * \param len Data length to write. - * \param compCback Write callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmWriteData(uint64_t id, const uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback); - -/*************************************************************************************************/ -/*! - * \brief Erase data. - * - * \param id Erase ID. - * \param compCback Write callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmEraseData(uint64_t id, WsfNvmCompEvent_t compCback); - -/*************************************************************************************************/ -/*! - * \brief Erase all data located in NVM storage. - * - * \param compCback Erase callback. - * - * \note Security Risk Warning. NVM storage could be shared by multiple Apps. - */ -/*************************************************************************************************/ -void WsfNvmEraseDataAll(WsfNvmCompEvent_t compCback); - -/*! \} */ /* WSF_NVM_API */ - -#ifdef __cplusplus -}; -#endif - -#endif /* WSF_NVM_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c deleted file mode 100644 index 4d1a268c940..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_nvm.c +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file wsf_nvm.c - * - * \brief NVM service. - * - * Copyright (c) 2019 Arm Ltd. All Rights Reserved. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include "wsf_types.h" -#include "wsf_nvm.h" -#include "wsf_assert.h" -#include "pal_flash.h" -#include "util/crc32.h" - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/*! NVM data start address. */ -#define WSF_NVM_START_ADDR 0x0000 - -/*! Reserved filecode. */ -#define WSF_NVM_RESERVED_FILECODE ((uint64_t)0) - -/* Unused (erased) filecode. */ -/* TODO: May depend on flash type */ -#define WSF_NVM_UNUSED_FILECODE ((uint64_t)0xFFFFFFFFFFFFFFFF) - -/*! Flash word size. */ -#define WSF_FLASH_WORD_SIZE 4 - -/*! Align value to word boundary. */ -#define WSF_NVM_WORD_ALIGN(x) (((x) + (WSF_FLASH_WORD_SIZE - 1)) & \ - ~(WSF_FLASH_WORD_SIZE - 1)) - -#define WSF_NVM_CRC_INIT_VALUE 0xFEDCBA98 - -/************************************************************************************************** - Data Types -**************************************************************************************************/ - -/*! \brief Header. */ -typedef struct -{ - uint64_t id; /*!< Stored data ID. */ - uint32_t len; /*!< Stored data length. */ - uint32_t headerCrc; /*!< CRC of this header. */ - uint32_t dataCrc; /*!< CRC of subsequent data. */ -} WsfNvmHeader_t; - -static struct -{ - uint32_t availAddr; /*!< Next available address for NVM write. */ - uint32_t sectorSize; /*!< Size of erase sector. */ - uint32_t totalSize; /*!< Total size of NVM storage. */ -} wsfNvmCb; - -/************************************************************************************************** - Global Functions -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Initialize the WSF NVM. - */ -/*************************************************************************************************/ -void WsfNvmInit(void) -{ - PalFlashInit(NULL); - wsfNvmCb.totalSize = PalNvmGetTotalSize(); - wsfNvmCb.sectorSize = PalNvmGetSectorSize(); - - WsfNvmHeader_t header; - uint32_t storageAddr = WSF_NVM_START_ADDR; - uint32_t headerCrc; - bool_t corruptData = FALSE; - - do - { - /* Read header. */ - PalFlashRead(&header, sizeof(header), storageAddr); - - if (header.id == WSF_NVM_UNUSED_FILECODE) - { - /* Found unused entry at end of used storage. */ - break; - } - - /* Iterate through stored data headers, looking for existing matching stored data header. */ - if (header.id != WSF_NVM_RESERVED_FILECODE) - { - /* Calculate CRC of header itself. */ - headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), - (uint8_t *)&header); - - if (headerCrc != header.headerCrc) - { - /* Corrupt header. */ - corruptData = TRUE; - break; - } - } - else - { - if ((header.headerCrc != 0) || (header.dataCrc !=0)) - { - /* Corrupt header. */ - corruptData = TRUE; - break; - } - } - - /* Move to next stored data block and read header. */ - storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - WSF_ASSERT((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize); - - } while ((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize); - - wsfNvmCb.availAddr = storageAddr; - - /* Check for corrupt data. */ - if (corruptData == TRUE) - { - /* Search for the first available location */ - while ((storageAddr - WSF_NVM_START_ADDR) < wsfNvmCb.totalSize) - { - PalFlashRead(&header.id, sizeof(header.id), storageAddr); - - if (header.id == WSF_NVM_UNUSED_FILECODE) - { - break; - } - - storageAddr += sizeof(header.id); - } - - /* Update the address of the first available location. align to sector boundary. */ - wsfNvmCb.availAddr = (storageAddr + wsfNvmCb.sectorSize - 1) & ~(wsfNvmCb.sectorSize - 1); - - /* Erase all data. */ - WsfNvmEraseDataAll(NULL); - } -} - -/*************************************************************************************************/ -/*! - * \brief Read data. - * - * \param id Stored data ID. - * \param pData Buffer to read to. - * \param len Data length to read. - * \param compCback Read callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmReadData(uint64_t id, uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) -{ - WsfNvmHeader_t header; - uint32_t headerCrc, dataCrc; - uint32_t storageAddr = WSF_NVM_START_ADDR; - bool_t findId = FALSE; - - WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); - - /* Read first header. */ - PalFlashRead(&header, sizeof(header), storageAddr); - - do - { - if (header.id == WSF_NVM_UNUSED_FILECODE) - { - /* Found unused entry at end of used storage. */ - break; - } - - /* Iterate through stored data headers, looking for existing matching stored data header. */ - if (header.id != WSF_NVM_RESERVED_FILECODE) - { - /* Calculate CRC of header itself. */ - headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), - (uint8_t *)&header); - - if (headerCrc != header.headerCrc) - { - /* Corrupt header. */ - /* TODO: Catastrophic failure? */ - break; - } - else if ((header.id == id) && (header.len == len)) - { - /* Valid header and matching ID - read data after header. */ - storageAddr += sizeof(header); - PalFlashRead(pData, header.len, storageAddr); - dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, header.len, pData); - if (dataCrc == header.dataCrc) - { - findId = TRUE; - } - break; - } - } - - /* Move to next stored data block and read header. */ - storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalFlashRead(&header, sizeof(header), storageAddr); - } while(1); - - if (compCback) - { - compCback(findId); - } - return findId; -} - -/*************************************************************************************************/ -/*! - * \brief Write data. - * - * \param id Stored data ID. - * \param pData Buffer to write. - * \param len Data length to write. - * \param compCback Write callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmWriteData(uint64_t id, const uint8_t *pData, uint16_t len, WsfNvmCompEvent_t compCback) -{ - WsfNvmHeader_t header; - uint32_t headerCrc, dataCrc; - uint32_t storageAddr = WSF_NVM_START_ADDR; - - WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); - WSF_ASSERT((wsfNvmCb.availAddr - WSF_NVM_START_ADDR) <= wsfNvmCb.totalSize); - - /* Read first header. */ - PalFlashRead(&header, sizeof(header), storageAddr); - - do - { - if (header.id == WSF_NVM_UNUSED_FILECODE) - { - /* Found unused entry at end of used storage. */ - break; - } - - /* Iterate through stored data headers, looking for existing matching stored data header. */ - if (header.id != WSF_NVM_RESERVED_FILECODE) - { - /* Calculate CRC of header itself. */ - headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), - (uint8_t *)&header); - - if (headerCrc != header.headerCrc) - { - /* Corrupt header. */ - /* TODO: Catastrophic failure? */ - break; - } - else if (header.id == id) - { - dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, len, pData); - if (dataCrc == header.dataCrc) - { - if (compCback) - { - compCback(TRUE); - } - return TRUE; - } - else - { - /* Valid header and matching ID - scratch header out. */ - header.id = WSF_NVM_RESERVED_FILECODE; - header.headerCrc = 0; - header.dataCrc = 0; - PalFlashWrite(&header, sizeof(header), storageAddr); - } - } - } - - /* Move to next stored data block and read header. */ - storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalFlashRead(&header, sizeof(header), storageAddr); - } while(1); - - /* After cycling through all headers, create a new stored data header and store data */ - header.id = id; - header.len = len; - header.headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), - (uint8_t *)&header); - header.dataCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, len, pData); - - PalFlashWrite(&header, sizeof(header), storageAddr); - PalFlashWrite((void *)pData, len, storageAddr + sizeof(header)); - - /* Move to next empty flash. */ - storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - wsfNvmCb.availAddr = storageAddr; - - if (compCback) - { - compCback((wsfNvmCb.availAddr - WSF_NVM_START_ADDR) <= wsfNvmCb.totalSize); - } - - return TRUE; -} - -/*************************************************************************************************/ -/*! - * \brief Erase data. - * - * \param id Erase ID. - * \param compCback Write callback. - * - * \return TRUE if NVM operation is successful, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t WsfNvmEraseData(uint64_t id, WsfNvmCompEvent_t compCback) -{ - WsfNvmHeader_t header; - uint32_t headerCrc; - uint32_t storageAddr = WSF_NVM_START_ADDR; - bool_t erased = FALSE; - - WSF_ASSERT(!((id == WSF_NVM_RESERVED_FILECODE) || (id == WSF_NVM_UNUSED_FILECODE))); - - /* Read first header. */ - PalFlashRead(&header, sizeof(header), storageAddr); - - do - { - if (header.id == WSF_NVM_UNUSED_FILECODE) - { - /* Found unused entry at end of used storage. */ - break; - } - - /* Iterate through stored data headers, looking for existing matching stored data header. */ - if (header.id != WSF_NVM_RESERVED_FILECODE) - { - headerCrc = CalcCrc32(WSF_NVM_CRC_INIT_VALUE, sizeof(header.id) + sizeof(header.len), - (uint8_t *)&header); - - if (headerCrc != header.headerCrc) - { - /* Corrupt header. */ - /* TODO: Catastrophic failure? */ - break; - } - else if (header.id == id) - { - header.id = WSF_NVM_RESERVED_FILECODE; - header.headerCrc = 0; - header.dataCrc = 0; - PalFlashWrite(&header, sizeof(header), storageAddr); - erased = TRUE; - } - } - - /* Move to next stored data block and read header. */ - storageAddr += WSF_NVM_WORD_ALIGN(header.len) + sizeof(header); - PalFlashRead(&header, sizeof(header), storageAddr); - } while(1); - - if (compCback) - { - compCback(erased); - } - return erased; -} - -/*************************************************************************************************/ -/*! - * \brief Erase all data located in NVM storage. - * - * \param compCback Erase callback. - * - * \note Security Risk Warning. NVM storage could be shared by multiple Apps. - */ -/*************************************************************************************************/ -void WsfNvmEraseDataAll(WsfNvmCompEvent_t compCback) -{ - for (uint32_t eraseAddr = WSF_NVM_START_ADDR; eraseAddr < wsfNvmCb.availAddr; eraseAddr += wsfNvmCb.sectorSize) - { - PalFlashEraseSector(1, eraseAddr); - } - wsfNvmCb.availAddr = WSF_NVM_START_ADDR; - - if (compCback) - { - compCback(TRUE); - } -} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp index 39723a3af26..4635b9b820c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp @@ -17,7 +17,6 @@ #include "mbed.h" #include "stack/platform/include/pal_types.h" #include "stack/platform/include/pal_uart.h" -#include "stack/platform/include/pal_nvm.h" #include "hal/ticker_api.h" #include "mbed_critical.h" @@ -50,34 +49,6 @@ MBED_WEAK void PalUartWriteData(PalUartId_t id, const uint8_t *pData, uint16_t l MBED_ERROR(function_not_implemented, "Provide implementation of PalUartWriteData"); } -/* NVM */ - -MBED_WEAK void PalNvmInit(PalNvmCback_t actCback) -{ - MBED_ERROR(function_not_implemented, "Provide implementation of PalNvmInit"); -} - -MBED_WEAK PalNvmState_t PalNvmGetState() -{ - MBED_ERROR(function_not_implemented, "Provide implementation of PalNvmGetState"); - return PAL_NVM_STATE_UNINIT; -} - -MBED_WEAK void PalNvmRead(void *pBuf, uint32_t size, uint32_t srcAddr) -{ - MBED_ERROR(function_not_implemented, "Provide implementation of PalNvmRead"); -} - -MBED_WEAK void PalNvmWrite(void *pBuf, uint32_t size, uint32_t dstAddr) -{ - MBED_ERROR(function_not_implemented, "Provide implementation of PalNvmWrite"); -} - -MBED_WEAK void PalNvmEraseSector(uint32_t size, uint32_t startAddr) -{ - MBED_ERROR(function_not_implemented, "Provide implementation of PalNvmEraseSector"); -} - /* LED */ MBED_WEAK void PalLedOn(uint8_t id) From 59528d6a180519cdc64514b367759f4bdce42132 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:26:06 +0100 Subject: [PATCH 06/38] expose WsfTimerNextExpiration in the wsf api --- .../TARGET_CORDIO/stack/wsf/include/wsf_timer.h | 13 +++++++++++++ .../stack/wsf/sources/port/baremetal/wsf_timer.c | 11 ++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_timer.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_timer.h index c6851a0efc7..c07c1ec5d14 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_timer.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/wsf_timer.h @@ -112,6 +112,19 @@ void WsfTimerStop(wsfTimer_t *pTimer); /*************************************************************************************************/ void WsfTimerUpdate(wsfTimerTicks_t ticks); +/*************************************************************************************************/ +/*! + * \brief Return the number of ticks until the next timer expiration. Note that this + * function can return zero even if a timer is running, indicating the timer + * has expired but has not yet been serviced. + * + * \param pTimerRunning Returns TRUE if a timer is running, FALSE if no timers running. + * + * \return The number of ticks until the next timer expiration. + */ +/*************************************************************************************************/ +wsfTimerTicks_t WsfTimerNextExpiration(bool_t *pTimerRunning); + /*************************************************************************************************/ /*! * \brief Service expired timers for the given task. This function is typically called only diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c index df2c9dd1e94..151fddca907 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c @@ -201,10 +201,12 @@ static uint32_t wsfTimerTicksToRtc(wsfTimerTicks_t wsfTicks) * function can return zero even if a timer is running, indicating a timer * has expired but has not yet been serviced. * + * \param pTimerRunning Returns TRUE if a timer is running, FALSE if no timers running. + * * \return The number of ticks until the next timer expiration. */ /*************************************************************************************************/ -static wsfTimerTicks_t wsfTimerNextExpiration(void) +wsfTimerTicks_t WsfTimerNextExpiration(bool_t *pTimerRunning) { wsfTimerTicks_t ticks; @@ -213,10 +215,12 @@ static wsfTimerTicks_t wsfTimerNextExpiration(void) if (wsfTimerTimerQueue.pHead == NULL) { + *pTimerRunning = FALSE; ticks = 0; } else { + *pTimerRunning = TRUE; ticks = ((wsfTimer_t *) wsfTimerTimerQueue.pHead)->ticks; } @@ -391,9 +395,10 @@ void WsfTimerSleep(void) return; } - nextExpiration = wsfTimerNextExpiration(); + bool_t running; + nextExpiration = WsfTimerNextExpiration(&running); - if (nextExpiration > 0) + if (running) { uint32_t awake = wsfTimerTicksToRtc(nextExpiration); uint32_t rtcCurrentTicks = PalRtcCounterGet(); From 4090f311075e8c3ce0a59df86343be407f0e9ae3 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:26:42 +0100 Subject: [PATCH 07/38] add missing services header --- .../stack/ble-host/include/svc_core.h | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h new file mode 100644 index 00000000000..3203d22f6c8 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/svc_core.h @@ -0,0 +1,185 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Example GATT and GAP service implementations. + * + * Copyright (c) 2009-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef SVC_CORE_H +#define SVC_CORE_H + + +#ifdef __cplusplus +extern "C" { +#endif + +/*! \addtogroup GATT_AND_GAP_SERVICE + * \{ */ + +/************************************************************************************************** + Handle Ranges +**************************************************************************************************/ +/** \name GAP Service Handles + * \note GAP -- RPAO characterstic added only when DM Privacy enabled + */ +/**@{*/ +#define GAP_START_HDL 0x01 /*!< \brief GAP start handle */ +#define GAP_END_HDL (GAP_MAX_HDL - 3) /*!< \brief GAP end handle */ +/**@}*/ + +/** \name GATT Service Handles + * + */ +/**@{*/ +#define GATT_START_HDL 0x10 /*!< \brief GATT start handle */ +#define GATT_END_HDL (GATT_MAX_HDL - 1) /*!< \brief GATT end handle */ +/**@}*/ + +/************************************************************************************************** + Handles +**************************************************************************************************/ + +/** \name GAP Service Handles + * + */ +/**@{*/ +/*! \brief GAP service handle */ +enum +{ + GAP_SVC_HDL = GAP_START_HDL, /*!< \brief GAP service declaration */ + GAP_DN_CH_HDL, /*!< \brief Device name characteristic */ + GAP_DN_HDL, /*!< \brief Device name */ + GAP_AP_CH_HDL, /*!< \brief Appearance characteristic */ + GAP_AP_HDL, /*!< \brief Appearance */ + GAP_CAR_CH_HDL, /*!< \brief Central address resolution characteristic */ + GAP_CAR_HDL, /*!< \brief Central address resolution */ + GAP_RPAO_CH_HDL, /*!< \brief Resolvable private address only characteristic */ + GAP_RPAO_HDL, /*!< \brief Resolvable private address only */ + GAP_MAX_HDL /*!< \brief GAP maximum handle */ +}; +/**@}*/ + +/** \name GATT Service Handles + * + */ +/**@{*/ +/*! \brief GATT service handles */ +enum +{ + GATT_SVC_HDL = GATT_START_HDL, /*!< \brief GATT service declaration */ + GATT_SC_CH_HDL, /*!< \brief Service changed characteristic */ + GATT_SC_HDL, /*!< \brief Service changed */ + GATT_SC_CH_CCC_HDL, /*!< \brief Service changed client characteristic configuration descriptor */ + GATT_CSF_CH_HDL, /*!< \brief Client supported features characteristic */ + GATT_CSF_HDL, /*!< \brief Client supported features */ + GATT_DBH_CH_HDL, /*!< \brief Database hash characteristic */ + GATT_DBH_HDL, /*!< \brief Database hash */ + GATT_SSF_CH_HDL, /*!< \brief Server supported features characteristic */ + GATT_SSF_HDL, /*!< \brief Server supported features */ + GATT_MAX_HDL /*!< \brief GATT maximum handle */ +}; +/**@}*/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Add the services to the attribute server. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreAddGroup(void); + +/*************************************************************************************************/ +/*! + * \brief Remove the services from the attribute server. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreRemoveGroup(void); + +/*************************************************************************************************/ +/*! + * \brief Register callbacks for the service. + * + * \param readCback Read callback function. + * \param writeCback Write callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreGattCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback); + +/*************************************************************************************************/ +/*! + * \brief Register callbacks for the service. + * + * \param readCback Read callback function. + * \param writeCback Write callback function. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreGapCbackRegister(attsReadCback_t readCback, attsWriteCback_t writeCback); + +/*************************************************************************************************/ +/*! + * \brief Update the central address resolution attribute value. + * + * \param value New value. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreGapCentAddrResUpdate(bool_t value); + +/*************************************************************************************************/ +/*! + * \brief Add the Resolvable Private Address Only (RPAO) characteristic to the GAP service. + * The RPAO characteristic should be added only when DM Privacy is enabled. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreGapAddRpaoCh(void); + +/*************************************************************************************************/ +/*! + * \brief Set the Server Supported Features (SSF) bitmask. + * + * \param value New value. + * + * \return None. + */ +/*************************************************************************************************/ +void SvcCoreGattSetSsf(uint8_t value); + +/*! \} */ /* GATT_AND_GAP_SERVICE */ + +#ifdef __cplusplus +}; +#endif + +#endif /* SVC_CORE_H */ + From 758b9587d21291e7051635a4f52eb812002623ad Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:27:02 +0100 Subject: [PATCH 08/38] missing wsf_types.h include --- .../stack/ble-host/sources/hci/dual_chip/hci_core_ps.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h index ebfe18ec5b7..41f07e8c252 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_core_ps.h @@ -28,6 +28,8 @@ extern "C" { #endif +#include "wsf_types.h" + /************************************************************************************************** Function Declarations **************************************************************************************************/ From 11dba2e9724ac9cf5770364d3518474481cae0a6 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:27:21 +0100 Subject: [PATCH 09/38] don't compile debug version of ecc by deafult --- .../stack/ble-host/sources/sec/common/sec_ecc_debug.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c index 1ab2e8583d1..e146af4f5dc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/sec/common/sec_ecc_debug.c @@ -22,6 +22,8 @@ */ /*************************************************************************************************/ +#if defined(SEC_ECC_CFG) + #include #include #include @@ -35,10 +37,6 @@ #include "hci_api.h" #include "util/calc128.h" -#ifndef SEC_ECC_CFG -#define SEC_ECC_CFG SEC_ECC_CFG_DEBUG -#endif - #if SEC_ECC_CFG == SEC_ECC_CFG_DEBUG /* Debug Keys */ @@ -158,3 +156,4 @@ void SecEccInit() } #endif /* SEC_ECC_CFG */ +#endif /* defined(SEC_ECC_CFG) */ From 260e5016dcfe1831ba0a739b349de80ed16c443e Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:27:47 +0100 Subject: [PATCH 10/38] fix cordio configuration --- .../targets/TARGET_CORDIO/mbed_lib.json | 9 +++++++-- .../stack/ble-host/sources/stack/cfg/cfg_stack.c | 16 ++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json b/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json index 4769723bc36..4b9234e7bd5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json @@ -1,6 +1,6 @@ { "name": "cordio", - "macros": [ "WSF_MS_PER_TICK=1" ], + "macros": ["WSF_MS_PER_TICK=1"], "config": { "max-connections": { "help": "Maximum number of connections", @@ -71,6 +71,11 @@ "preferred-tx-power": { "help": "Preferred value of tx power in dbm (-128,127). This value is not guaranteed and relies on existing support in the HCI driver.", "value": 0 + }, + "max-eatt-channels": { + "help": "Maximum number of EATT channels per DM connection.", + "value": 1, + "macro_name": "EATT_CONN_CHAN_MAX" } } -} +} \ No newline at end of file diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c index f25bd35d8ef..eb394de9565 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/cfg/cfg_stack.c @@ -65,13 +65,17 @@ l2cCfg_t *pL2cCfg = (l2cCfg_t *) &l2cCfg; ATT **************************************************************************************************/ +#if MBED_CONF_CORDIO_DESIRED_ATT_MTU < ATT_DEFAULT_MTU || MBED_CONF_CORDIO_DESIRED_ATT_MTU > ATT_MAX_MTU +#error "CORDIO_CFG_DESIRED_ATT_MTU value is outside valid range" +#endif + /* Configuration structure */ -const attCfg_t attCfg = +attCfg_t attCfg = { - 15, /* ATT server service discovery connection idle timeout in seconds */ - ATT_DEFAULT_MTU, /* desired ATT MTU */ - ATT_MAX_TRANS_TIMEOUT, /* transcation timeout in seconds */ - 4 /* number of queued prepare writes supported by server */ + 15, /* ATT server service discovery connection idle timeout in seconds */ + MBED_CONF_CORDIO_DESIRED_ATT_MTU, /* desired ATT MTU */ + ATT_MAX_TRANS_TIMEOUT, /* transaction timeout in seconds */ + MBED_CONF_CORDIO_MAX_PREPARED_WRITES /* number of queued prepare writes supported by server */ }; /* Configuration pointer */ @@ -104,7 +108,7 @@ WSF_CT_ASSERT(EATT_CONN_CHAN_MAX <= L2C_COC_CHAN_MAX); **************************************************************************************************/ /* Configuration structure */ -const smpCfg_t smpCfg = +smpCfg_t smpCfg = { 500, /* 'Repeated attempts' timeout in msec */ SMP_IO_NO_IN_NO_OUT, /* I/O Capability */ From c61f84b97cc4a8ad58f960f630e8d2a654ead540 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:51:07 +0100 Subject: [PATCH 11/38] remove pointless heap count --- .../stack/wsf/sources/port/baremetal/wsf_heap.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c index cb5a444969c..a16fe67f282 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_heap.c @@ -37,8 +37,6 @@ extern uint8_t *SystemHeapStart; extern uint32_t SystemHeapSize; -extern unsigned long __heap_end__; -extern unsigned long __heap_start__; /*************************************************************************************************/ /*! @@ -89,9 +87,5 @@ uint32_t WsfHeapCountAvailable(void) /*************************************************************************************************/ uint32_t WsfHeapCountUsed(void) { -#ifdef __GNUC__ - return ((uint8_t *)&__heap_end__ - (uint8_t *)&__heap_start__) - SystemHeapSize; -#else return 0; -#endif } From c4afea26fa6ba3f42c2339940af01e70cc6c234b Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:51:49 +0100 Subject: [PATCH 12/38] remember if key was authenticated --- .../targets/TARGET_CORDIO/stack/ble-host/include/att_api.h | 3 ++- .../stack/ble-host/sources/stack/att/atts_sign.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h index fd285de1828..a0649f26c0f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/att_api.h @@ -793,11 +793,12 @@ void AttsContinueWriteReq(dmConnId_t connId, uint16_t handle, uint8_t status); * * \param connId DM connection ID. * \param pCsrk Pointer to data signing key (CSRK). + * \param authenticated True if CSRK is authenticated and false otherwise. * * \return None. */ /*************************************************************************************************/ -void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk); +void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk, bool_t authenticated); /*************************************************************************************************/ /*! diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c index 5cadd92e465..a566a6794b5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c @@ -59,6 +59,7 @@ typedef struct uint32_t signCounter; /* sign counter for this connection */ uint8_t *pCsrk; /* signing key for this connection */ attsSignBuf_t *pBuf; /* current data being processed */ + bool_t authenticated; /* Indicate if the CSRK is authenticated or not */ } attsSignCcb_t; /* ATTS signed PDU control block */ @@ -342,13 +343,15 @@ void AttsSignInit(void) * * \param connId DM connection ID. * \param pCsrk Pointer to data signing key (CSRK). + * \param authenticated True if CSRK is authenticated and false otherwise. * * \return None. */ /*************************************************************************************************/ -void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk) +void AttsSetCsrk(dmConnId_t connId, uint8_t *pCsrk, bool_t authenticated) { attsSignCcbByConnId(connId)->pCsrk = pCsrk; + attsSignCcbByConnId(connId)->authenticated = authenticated; } /*************************************************************************************************/ From d3bda92bee0fbcfa4cdb6922b567831fd1129a90 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 8 Jun 2020 18:52:05 +0100 Subject: [PATCH 13/38] fix signed writes --- .../ble-host/sources/stack/att/atts_sign.c | 72 +++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c index a566a6794b5..ce0e54b9639 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/att/atts_sign.c @@ -167,53 +167,69 @@ static void attsProcSignedWrite(attsCcb_t *pCcb, uint16_t len, uint8_t *pPacket) /* find attribute */ if ((pAttr = attsFindByHandle(handle, &pGroup)) != NULL) { - /* verify permissions */ - if (attsPermissions(pCcb->connId, ATTS_PERMIT_WRITE, handle, pAttr->permissions) != ATT_SUCCESS) + /* verify signed write is permitted */ + if ((pAttr->settings & ATTS_SET_ALLOW_SIGNED) == 0) { return; } - /* verify signed write is permitted */ - else if ((pAttr->settings & ATTS_SET_ALLOW_SIGNED) == 0) + + /* verify that csrk is present */ + if (attsSignCcbByConnId(pCcb->pMainCcb->connId)->pCsrk == NULL) { + return; + } + + /* verify basic permissions */ + if ((pAttr->permissions & (ATTS_PERMIT_WRITE | ATTS_PERMIT_WRITE_ENC)) == 0) { return; } + + /* verify authentication */ + if ((pAttr->permissions & ATTS_PERMIT_WRITE_AUTH) && + (attsSignCcbByConnId(pCcb->pMainCcb->connId)->authenticated == 0)) + { + return; + } + + /* Note: authorization not verified at this stage as it is reserved for lesc + writes; authorization occurs latter when the write cb is called */ + /* verify write length, fixed length */ - else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) && + if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) && (writeLen != pAttr->maxLen)) { return; } + /* verify write length, variable length */ - else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) != 0) && + if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) != 0) && (writeLen > pAttr->maxLen)) { return; } - else + + /* allocate buffer to store packet and parameters */ + if ((pBuf = WsfBufAlloc(sizeof(attsSignBuf_t) - 1 + len)) != NULL) { - /* allocate buffer to store packet and parameters */ - if ((pBuf = WsfBufAlloc(sizeof(attsSignBuf_t) - 1 + len)) != NULL) - { - /* initialize buffer */ - pBuf->pCcb = pCcb->pMainCcb; - pBuf->handle = handle; - pBuf->writeLen = writeLen; - pBuf->connId = pCcb->connId; - memcpy(pBuf->packet, (pPacket + L2C_PAYLOAD_START), len); + /* initialize buffer */ + pBuf->pCcb = pCcb->pMainCcb; + pBuf->handle = handle; + pBuf->writeLen = writeLen; + pBuf->connId = pCcb->connId; + memcpy(pBuf->packet, (pPacket + L2C_PAYLOAD_START), len); - /* check if a signed write is already in progress */ - pSignCcb = attsSignCcbByConnId(pCcb->connId); + /* check if a signed write is already in progress */ + pSignCcb = attsSignCcbByConnId(pCcb->connId); - if (pSignCcb->pBuf != NULL) - { - /* signed write in progress; queue packet */ - WsfQueueEnq(&attsSignCb.msgQueue, pBuf); - } - else - { - /* start signed data processing */ - attsSignedWriteStart(pSignCcb, pBuf); - } + if (pSignCcb->pBuf != NULL) + { + /* signed write in progress; queue packet */ + WsfQueueEnq(&attsSignCb.msgQueue, pBuf); + } + else + { + /* start signed data processing */ + attsSignedWriteStart(pSignCcb, pBuf); } } } From ebf9ec963d543f8442a3ef1f5200b2711c393d55 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Tue, 9 Jun 2020 08:46:43 +0100 Subject: [PATCH 14/38] copy advertising data into the message --- .../TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c | 4 ++-- .../TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h | 4 ++-- .../TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c index b3431909a9f..933092c0eef 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.c @@ -155,14 +155,14 @@ void DmAdvSetData(uint8_t advHandle, uint8_t op, uint8_t location, uint8_t len, WSF_ASSERT((location == DM_DATA_LOC_SCAN) || (location == DM_DATA_LOC_ADV)); WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); - if ((pMsg = WsfMsgAlloc(sizeof(dmAdvApiSetData_t))) != NULL) + if ((pMsg = WsfMsgAlloc(sizeof(dmAdvApiSetData_t) + len)) != NULL) { pMsg->hdr.event = DM_ADV_MSG_API_SET_DATA; pMsg->advHandle = advHandle; pMsg->op = op; pMsg->location = location; pMsg->len = len; - pMsg->pData = pData; + memcpy(pMsg->pData, pData, len); WsfMsgSend(dmCb.handlerId, pMsg); } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h index 7fca43289a6..d7d1ed1d9b0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv.h @@ -106,7 +106,7 @@ typedef struct uint8_t op; uint8_t location; uint8_t len; - uint8_t *pData; + uint8_t pData[]; } dmAdvApiSetData_t; /* Data structure for DM_ADV_MSG_API_START */ @@ -156,7 +156,7 @@ typedef struct uint8_t advHandle; uint8_t op; uint8_t len; - uint8_t *pData; + uint8_t pData[]; } dmAdvPerApiSetData_t; /* Data structure for DM_ADV_PER_MSG_API_START */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c index 635daf02f71..9f7c956740d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_adv_ae.c @@ -1669,13 +1669,13 @@ void DmPerAdvSetData(uint8_t advHandle, uint8_t op, uint8_t len, uint8_t *pData) WSF_ASSERT(advHandle < DM_NUM_ADV_SETS); WSF_ASSERT(len <= HCI_PER_ADV_DATA_LEN); - if ((pMsg = WsfMsgAlloc(sizeof(dmAdvPerApiSetData_t))) != NULL) + if ((pMsg = WsfMsgAlloc(sizeof(dmAdvPerApiSetData_t) + len)) != NULL) { pMsg->hdr.event = DM_ADV_PER_MSG_API_SET_DATA; pMsg->advHandle = advHandle; pMsg->op = op; pMsg->len = len; - pMsg->pData = pData; + memcpy(pMsg->pData, pData, len); WsfMsgSend(dmCb.handlerId, pMsg); } } From a40d0cb282885af46f0d7af36e3bdc9edfd85e75 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Tue, 9 Jun 2020 09:24:31 +0100 Subject: [PATCH 15/38] fix error message --- .../TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp index 4635b9b820c..fa2f10e3d1a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp @@ -80,7 +80,7 @@ MBED_WEAK void PalRtcDisableCompareIrq() MBED_WEAK uint32_t PalRtcCounterGet() { - MBED_ERROR(function_not_implemented, "Provide implementation of PalRtcDisableCompareIrq"); + MBED_ERROR(function_not_implemented, "Provide implementation of PalRtcCounterGet"); return 0; } From c2bc9a43859a33bf7a184e0907e4229c9578d755 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Tue, 9 Jun 2020 09:25:03 +0100 Subject: [PATCH 16/38] avoid redundant call on timer init --- .../TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c index 151fddca907..956ee07d366 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/sources/port/baremetal/wsf_timer.c @@ -240,7 +240,7 @@ void WsfTimerInit(void) { WSF_QUEUE_INIT(&wsfTimerTimerQueue); - wsfTimerRtcLastTicks = PalRtcCounterGet(); + wsfTimerRtcLastTicks = 0; wsfTimerRtcRemainder = 0; } From be80c46e9acd17de5f5adae1155921eb094b6ce8 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 09:26:28 +0100 Subject: [PATCH 17/38] update cordio LL files to 20.05r --- .../stack/controller/include/ble/bb_ble_api.h | 95 +- .../controller/include/ble/bb_ble_api_op.h | 134 +- .../include/ble/bb_ble_api_pdufilt.h | 39 +- .../include/ble/bb_ble_api_periodiclist.h | 39 +- .../include/ble/bb_ble_api_reslist.h | 43 +- .../include/ble/bb_ble_api_whitelist.h | 43 +- .../include/ble/bb_ble_sniffer_api.h | 163 ++ .../stack/controller/include/ble/lhci_api.h | 45 +- .../stack/controller/include/ble/ll_api.h | 1042 +++++++--- .../stack/controller/include/ble/ll_defs.h | 492 ----- .../controller/include/ble/ll_init_api.h | 40 +- .../stack/controller/include/ble/ll_math.h | 49 +- .../controller/include/ble/sch_api_ble.h | 48 +- .../stack/controller/include/common/bb_api.h | 119 +- .../stack/controller/include/common/cfg_mac.h | 42 +- .../controller/include/common/cfg_mac_ble.h | 55 +- .../controller/include/common/chci_api.h | 56 +- .../stack/controller/include/common/chci_tr.h | 50 +- .../stack/controller/include/common/sch_api.h | 37 +- .../sources/ble/bb/bb_ble_adv_master.c | 187 +- .../sources/ble/bb/bb_ble_adv_master_ae.c | 208 +- .../sources/ble/bb/bb_ble_adv_slave.c | 150 +- .../sources/ble/bb/bb_ble_adv_slave_ae.c | 163 +- .../sources/ble/bb/bb_ble_bis_master.c | 201 ++ .../sources/ble/bb/bb_ble_bis_slave.c | 151 ++ .../controller/sources/ble/bb/bb_ble_cis.c | 104 + .../sources/ble/bb/bb_ble_cis_master.c | 344 +++ .../sources/ble/bb/bb_ble_cis_slave.c | 384 ++++ .../controller/sources/ble/bb/bb_ble_conn.c | 55 +- .../sources/ble/bb/bb_ble_conn_master.c | 107 +- .../sources/ble/bb/bb_ble_conn_slave.c | 108 +- .../ble/bb/{bb_ble_test.c => bb_ble_dtm.c} | 74 +- .../controller/sources/ble/bb/bb_ble_int.h | 91 +- .../controller/sources/ble/bb/bb_ble_main.c | 68 +- .../sources/ble/bb/bb_ble_pdufilt.c | 85 +- .../sources/ble/bb/bb_ble_periodiclist.c | 41 +- .../sources/ble/bb/bb_ble_reslist.c | 51 +- .../sources/ble/bb/bb_ble_sniffer.c | 397 ++++ .../sources/ble/bb/bb_ble_whitelist.c | 43 +- .../controller/sources/ble/include/lctr_api.h | 79 +- .../sources/ble/include/lctr_api_adv_acad.h | 85 + .../sources/ble/include/lctr_api_adv_master.h | 35 +- .../ble/include/lctr_api_adv_master_ae.h | 36 +- .../sources/ble/include/lctr_api_adv_slave.h | 35 +- .../ble/include/lctr_api_adv_slave_ae.h | 49 +- .../sources/ble/include/lctr_api_bis_master.h | 102 + .../sources/ble/include/lctr_api_bis_slave.h | 82 + .../sources/ble/include/lctr_api_cis.h | 98 + .../sources/ble/include/lctr_api_cis_master.h | 52 + .../sources/ble/include/lctr_api_cis_slave.h | 50 + .../sources/ble/include/lctr_api_conn.h | 57 +- .../sources/ble/include/lctr_api_conn_cs2.h | 35 +- .../ble/include/lctr_api_init_master.h | 35 +- .../ble/include/lctr_api_init_master_ae.h | 40 +- .../sources/ble/include/lctr_api_iso.h | 60 + .../sources/ble/include/lctr_api_pc.h | 47 + .../sources/ble/include/lctr_api_phy.h | 35 +- .../sources/ble/include/lctr_api_priv.h | 35 +- .../sources/ble/include/lctr_api_sc.h | 35 +- .../controller/sources/ble/include/lmgr_api.h | 47 +- .../sources/ble/include/lmgr_api_adv_master.h | 39 +- .../ble/include/lmgr_api_adv_master_ae.h | 35 +- .../sources/ble/include/lmgr_api_adv_slave.h | 41 +- .../ble/include/lmgr_api_adv_slave_ae.h | 35 +- .../sources/ble/include/lmgr_api_cis_master.h | 72 + .../sources/ble/include/lmgr_api_cis_slave.h | 64 + .../sources/ble/include/lmgr_api_conn.h | 35 +- .../sources/ble/include/lmgr_api_iso.h | 80 + .../sources/ble/include/lmgr_api_priv.h | 35 +- .../sources/ble/include/lmgr_api_sc.h | 35 +- .../stack/controller/sources/ble/init/init.c | 88 +- .../controller/sources/ble/init/init_ctr.c | 58 +- .../sources/ble/lctr/lctr_act_adv_master.c | 55 +- .../sources/ble/lctr/lctr_act_adv_master_ae.c | 184 +- .../sources/ble/lctr/lctr_act_adv_slave.c | 75 +- .../sources/ble/lctr/lctr_act_adv_slave_ae.c | 161 +- .../sources/ble/lctr/lctr_act_bis_master.c | 271 +++ .../sources/ble/lctr/lctr_act_bis_slave.c | 211 ++ .../sources/ble/lctr/lctr_act_cis.c | 538 +++++ .../sources/ble/lctr/lctr_act_cis_master.c | 481 +++++ .../sources/ble/lctr/lctr_act_cis_slave.c | 508 +++++ .../sources/ble/lctr/lctr_act_conn.c | 197 +- .../sources/ble/lctr/lctr_act_conn_master.c | 41 +- .../ble/lctr/lctr_act_conn_master_ae.c | 42 +- .../sources/ble/lctr/lctr_act_conn_past.c | 85 +- .../sources/ble/lctr/lctr_act_enc.c | 89 +- .../sources/ble/lctr/lctr_act_enc_master.c | 41 +- .../sources/ble/lctr/lctr_act_init_master.c | 64 +- .../ble/lctr/lctr_act_init_master_ae.c | 50 +- .../controller/sources/ble/lctr/lctr_act_pc.c | 650 ++++++ .../sources/ble/lctr/lctr_act_phy.c | 53 +- .../controller/sources/ble/lctr/lctr_int.h | 143 +- .../sources/ble/lctr/lctr_int_adv_ae.h | 70 +- .../sources/ble/lctr/lctr_int_adv_master.h | 50 +- .../sources/ble/lctr/lctr_int_adv_master_ae.h | 100 +- .../sources/ble/lctr/lctr_int_adv_slave.h | 37 +- .../sources/ble/lctr/lctr_int_adv_slave_ae.h | 106 +- .../sources/ble/lctr/lctr_int_bis.h | 292 +++ .../sources/ble/lctr/lctr_int_bis_master.h | 99 + .../sources/ble/lctr/lctr_int_bis_slave.h | 95 + .../sources/ble/lctr/lctr_int_cis.h | 535 +++++ .../sources/ble/lctr/lctr_int_cis_master.h | 115 + .../sources/ble/lctr/lctr_int_cis_slave.h | 107 + .../sources/ble/lctr/lctr_int_conn.h | 229 +- .../sources/ble/lctr/lctr_int_conn_master.h | 36 +- .../sources/ble/lctr/lctr_int_conn_slave.h | 35 +- .../sources/ble/lctr/lctr_int_enc_master.h | 35 +- .../sources/ble/lctr/lctr_int_enc_slave.h | 35 +- .../sources/ble/lctr/lctr_int_init_master.h | 35 +- .../ble/lctr/lctr_int_init_master_ae.h | 36 +- .../sources/ble/lctr/lctr_int_iso.h | 263 +++ .../sources/ble/lctr/lctr_int_master_phy.h | 35 +- .../controller/sources/ble/lctr/lctr_int_pc.h | 76 + .../sources/ble/lctr/lctr_int_priv.h | 35 +- .../sources/ble/lctr/lctr_int_slave_phy.h | 35 +- .../sources/ble/lctr/lctr_isr_adv_master.c | 65 +- .../sources/ble/lctr/lctr_isr_adv_master_ae.c | 462 +++-- .../sources/ble/lctr/lctr_isr_adv_slave.c | 79 +- .../sources/ble/lctr/lctr_isr_adv_slave_ae.c | 180 +- .../sources/ble/lctr/lctr_isr_bis_master.c | 937 +++++++++ .../sources/ble/lctr/lctr_isr_bis_slave.c | 771 +++++++ .../sources/ble/lctr/lctr_isr_cis.c | 358 ++++ .../sources/ble/lctr/lctr_isr_cis_master.c | 1205 +++++++++++ .../sources/ble/lctr/lctr_isr_cis_slave.c | 1295 ++++++++++++ .../sources/ble/lctr/lctr_isr_conn.c | 53 +- .../sources/ble/lctr/lctr_isr_conn_master.c | 127 +- .../sources/ble/lctr/lctr_isr_conn_slave.c | 142 +- .../sources/ble/lctr/lctr_isr_init_master.c | 123 +- .../ble/lctr/lctr_isr_init_master_ae.c | 322 ++- .../controller/sources/ble/lctr/lctr_main.c | 199 +- .../sources/ble/lctr/lctr_main_adv_master.c | 73 +- .../ble/lctr/lctr_main_adv_master_ae.c | 331 +-- .../sources/ble/lctr/lctr_main_adv_slave.c | 130 +- .../sources/ble/lctr/lctr_main_adv_slave_ae.c | 274 ++- .../sources/ble/lctr/lctr_main_bis.c | 1426 +++++++++++++ .../sources/ble/lctr/lctr_main_bis_master.c | 517 +++++ .../sources/ble/lctr/lctr_main_bis_slave.c | 966 +++++++++ .../sources/ble/lctr/lctr_main_cis.c | 1843 +++++++++++++++++ .../sources/ble/lctr/lctr_main_cis_master.c | 1127 ++++++++++ .../sources/ble/lctr/lctr_main_cis_slave.c | 416 ++++ .../sources/ble/lctr/lctr_main_conn.c | 446 +++- .../sources/ble/lctr/lctr_main_conn_cs2.c | 37 +- .../sources/ble/lctr/lctr_main_conn_data.c | 103 +- .../sources/ble/lctr/lctr_main_conn_master.c | 190 +- .../sources/ble/lctr/lctr_main_conn_slave.c | 126 +- .../sources/ble/lctr/lctr_main_enc_master.c | 41 +- .../sources/ble/lctr/lctr_main_enc_slave.c | 43 +- .../sources/ble/lctr/lctr_main_init_master.c | 72 +- .../ble/lctr/lctr_main_init_master_ae.c | 77 +- .../sources/ble/lctr/lctr_main_iso.c | 1196 +++++++++++ .../sources/ble/lctr/lctr_main_iso_data.c | 1181 +++++++++++ .../sources/ble/lctr/lctr_main_master_phy.c | 37 +- .../sources/ble/lctr/lctr_main_past.c | 37 +- .../sources/ble/lctr/lctr_main_pc.c | 320 +++ .../sources/ble/lctr/lctr_main_priv.c | 45 +- .../sources/ble/lctr/lctr_main_sc.c | 63 +- .../sources/ble/lctr/lctr_main_slave_phy.c | 37 +- .../sources/ble/lctr/lctr_pdu_adv.h | 35 +- .../sources/ble/lctr/lctr_pdu_adv_ae.h | 43 +- .../sources/ble/lctr/lctr_pdu_adv_master_ae.c | 139 +- .../sources/ble/lctr/lctr_pdu_adv_slave.c | 36 +- .../sources/ble/lctr/lctr_pdu_adv_slave_ae.c | 213 +- .../sources/ble/lctr/lctr_pdu_bis.c | 171 ++ .../sources/ble/lctr/lctr_pdu_conn.c | 139 +- .../sources/ble/lctr/lctr_pdu_conn.h | 70 +- .../sources/ble/lctr/lctr_pdu_enc.c | 35 +- .../sources/ble/lctr/lctr_pdu_iso.c | 242 +++ .../sources/ble/lctr/lctr_pdu_iso.h | 149 ++ .../sources/ble/lctr/lctr_sm_adv_master.c | 37 +- .../sources/ble/lctr/lctr_sm_adv_master_ae.c | 47 +- .../sources/ble/lctr/lctr_sm_adv_slave.c | 37 +- .../sources/ble/lctr/lctr_sm_adv_slave_ae.c | 67 +- .../sources/ble/lctr/lctr_sm_bis_master.c | 168 ++ .../sources/ble/lctr/lctr_sm_bis_slave.c | 129 ++ .../controller/sources/ble/lctr/lctr_sm_cis.c | 169 ++ .../sources/ble/lctr/lctr_sm_conn_master.c | 41 +- .../sources/ble/lctr/lctr_sm_conn_slave.c | 47 +- .../sources/ble/lctr/lctr_sm_init_master.c | 37 +- .../sources/ble/lctr/lctr_sm_init_master_ae.c | 37 +- .../sources/ble/lctr/lctr_sm_llcp_cis.c | 328 +++ .../ble/lctr/lctr_sm_llcp_cis_master.c | 297 +++ .../sources/ble/lctr/lctr_sm_llcp_cis_slave.c | 382 ++++ .../sources/ble/lctr/lctr_sm_llcp_conn.c | 43 +- .../ble/lctr/lctr_sm_llcp_conn_master.c | 67 +- .../ble/lctr/lctr_sm_llcp_conn_slave.c | 75 +- .../ble/lctr/lctr_sm_llcp_enc_master.c | 59 +- .../sources/ble/lctr/lctr_sm_llcp_enc_slave.c | 57 +- .../ble/lctr/lctr_sm_llcp_master_phy.c | 55 +- .../sources/ble/lctr/lctr_sm_llcp_pc.c | 546 +++++ .../sources/ble/lctr/lctr_sm_llcp_slave_phy.c | 81 +- .../controller/sources/ble/lhci/lhci_cmd.c | 48 +- .../sources/ble/lhci/lhci_cmd_adv_master.c | 37 +- .../sources/ble/lhci/lhci_cmd_adv_master_ae.c | 51 +- .../sources/ble/lhci/lhci_cmd_adv_priv.c | 37 +- .../sources/ble/lhci/lhci_cmd_adv_slave.c | 37 +- .../sources/ble/lhci/lhci_cmd_adv_slave_ae.c | 39 +- .../sources/ble/lhci/lhci_cmd_bis_master.c | 90 + .../sources/ble/lhci/lhci_cmd_bis_slave.c | 121 ++ .../sources/ble/lhci/lhci_cmd_cis_master.c | 308 +++ .../sources/ble/lhci/lhci_cmd_cis_slave.c | 138 ++ .../sources/ble/lhci/lhci_cmd_conn.c | 44 +- .../sources/ble/lhci/lhci_cmd_conn_master.c | 37 +- .../ble/lhci/lhci_cmd_conn_master_ae.c | 37 +- .../sources/ble/lhci/lhci_cmd_conn_priv.c | 37 +- .../sources/ble/lhci/lhci_cmd_enc_master.c | 35 +- .../sources/ble/lhci/lhci_cmd_enc_slave.c | 37 +- .../sources/ble/lhci/lhci_cmd_iso.c | 587 ++++++ .../sources/ble/lhci/lhci_cmd_past.c | 35 +- .../controller/sources/ble/lhci/lhci_cmd_pc.c | 215 ++ .../sources/ble/lhci/lhci_cmd_phy.c | 37 +- .../controller/sources/ble/lhci/lhci_cmd_sc.c | 35 +- .../controller/sources/ble/lhci/lhci_cmd_vs.c | 85 +- .../sources/ble/lhci/lhci_cmd_vs_adv_master.c | 35 +- .../ble/lhci/lhci_cmd_vs_adv_master_ae.c | 35 +- .../sources/ble/lhci/lhci_cmd_vs_adv_slave.c | 35 +- .../ble/lhci/lhci_cmd_vs_adv_slave_ae.c | 35 +- .../sources/ble/lhci/lhci_cmd_vs_conn.c | 51 +- .../ble/lhci/lhci_cmd_vs_conn_master.c | 35 +- .../sources/ble/lhci/lhci_cmd_vs_enc_slave.c | 35 +- .../sources/ble/lhci/lhci_cmd_vs_ext.c | 41 - .../sources/ble/lhci/lhci_cmd_vs_iso.c | 164 ++ .../sources/ble/lhci/lhci_cmd_vs_sc.c | 35 +- .../controller/sources/ble/lhci/lhci_evt.c | 39 +- .../sources/ble/lhci/lhci_evt_adv_master.c | 35 +- .../sources/ble/lhci/lhci_evt_adv_master_ae.c | 53 +- .../sources/ble/lhci/lhci_evt_adv_slave.c | 35 +- .../sources/ble/lhci/lhci_evt_adv_slave_ae.c | 39 +- .../sources/ble/lhci/lhci_evt_bis_master.c | 183 ++ .../sources/ble/lhci/lhci_evt_bis_slave.c | 129 ++ .../sources/ble/lhci/lhci_evt_cis_master.c | 115 + .../sources/ble/lhci/lhci_evt_cis_slave.c | 101 + .../sources/ble/lhci/lhci_evt_conn.c | 116 +- .../sources/ble/lhci/lhci_evt_conn_cs2.c | 35 +- .../sources/ble/lhci/lhci_evt_conn_master.c | 35 +- .../sources/ble/lhci/lhci_evt_conn_priv.c | 35 +- .../sources/ble/lhci/lhci_evt_enc_master.c | 35 +- .../sources/ble/lhci/lhci_evt_enc_slave.c | 35 +- .../sources/ble/lhci/lhci_evt_iso.c | 203 ++ .../controller/sources/ble/lhci/lhci_evt_pc.c | 124 ++ .../sources/ble/lhci/lhci_evt_phy.c | 35 +- .../controller/sources/ble/lhci/lhci_evt_sc.c | 35 +- .../controller/sources/ble/lhci/lhci_evt_vs.c | 191 +- .../controller/sources/ble/lhci/lhci_init.c | 41 +- .../sources/ble/lhci/lhci_init_adv_master.c | 37 +- .../ble/lhci/lhci_init_adv_master_ae.c | 37 +- .../sources/ble/lhci/lhci_init_adv_priv.c | 37 +- .../sources/ble/lhci/lhci_init_adv_slave.c | 37 +- .../sources/ble/lhci/lhci_init_adv_slave_ae.c | 37 +- .../sources/ble/lhci/lhci_init_bis_master.c | 40 + .../sources/ble/lhci/lhci_init_bis_slave.c | 40 + .../sources/ble/lhci/lhci_init_cis_master.c | 40 + .../sources/ble/lhci/lhci_init_cis_slave.c | 40 + .../sources/ble/lhci/lhci_init_conn.c | 37 +- .../sources/ble/lhci/lhci_init_conn_cs2.c | 37 +- .../sources/ble/lhci/lhci_init_conn_master.c | 37 +- .../ble/lhci/lhci_init_conn_master_ae.c | 37 +- .../sources/ble/lhci/lhci_init_conn_priv.c | 37 +- .../sources/ble/lhci/lhci_init_enc_master.c | 37 +- .../sources/ble/lhci/lhci_init_enc_slave.c | 37 +- .../sources/ble/lhci/lhci_init_iso.c | 69 + .../sources/ble/lhci/lhci_init_past.c | 37 +- .../sources/ble/lhci/lhci_init_pc.c | 38 + .../sources/ble/lhci/lhci_init_phy.c | 37 +- .../sources/ble/lhci/lhci_init_sc.c | 37 +- .../controller/sources/ble/lhci/lhci_int.h | 122 +- .../controller/sources/ble/lhci/lhci_main.c | 182 +- .../sources/ble/lhci/lhci_main_iso.c | 62 + .../stack/controller/sources/ble/ll/ll_init.c | 79 +- .../sources/ble/ll/ll_init_adv_master.c | 37 +- .../sources/ble/ll/ll_init_adv_master_ae.c | 37 +- .../sources/ble/ll/ll_init_adv_slave.c | 37 +- .../sources/ble/ll/ll_init_adv_slave_ae.c | 37 +- .../sources/ble/ll/ll_init_bis_master.c | 42 + .../sources/ble/ll/ll_init_bis_slave.c | 71 + .../sources/ble/ll/ll_init_cis_master.c | 45 + .../sources/ble/ll/ll_init_cis_slave.c | 73 + .../sources/ble/ll/ll_init_conn_cs2.c | 37 +- .../sources/ble/ll/ll_init_conn_master.c | 37 +- .../sources/ble/ll/ll_init_conn_slave.c | 39 +- .../sources/ble/ll/ll_init_enc_master.c | 37 +- .../sources/ble/ll/ll_init_enc_slave.c | 37 +- .../sources/ble/ll/ll_init_init_master.c | 37 +- .../sources/ble/ll/ll_init_init_master_ae.c | 37 +- .../controller/sources/ble/ll/ll_init_iso.c | 70 + .../sources/ble/ll/ll_init_master_phy.c | 37 +- .../controller/sources/ble/ll/ll_init_past.c | 37 +- .../controller/sources/ble/ll/ll_init_pc.c | 39 + .../controller/sources/ble/ll/ll_init_priv.c | 37 +- .../controller/sources/ble/ll/ll_init_sc.c | 37 +- .../sources/ble/ll/ll_init_slave_phy.c | 37 +- .../stack/controller/sources/ble/ll/ll_main.c | 157 +- .../sources/ble/ll/ll_main_adv_master.c | 37 +- .../sources/ble/ll/ll_main_adv_master_ae.c | 88 +- .../sources/ble/ll/ll_main_adv_slave.c | 43 +- .../sources/ble/ll/ll_main_adv_slave_ae.c | 62 +- .../sources/ble/ll/ll_main_bis_master.c | 128 ++ .../sources/ble/ll/ll_main_bis_slave.c | 355 ++++ .../sources/ble/ll/ll_main_cis_master.c | 500 +++++ .../sources/ble/ll/ll_main_cis_slave.c | 75 + .../controller/sources/ble/ll/ll_main_conn.c | 224 +- .../sources/ble/ll/ll_main_conn_master.c | 37 +- .../sources/ble/ll/ll_main_conn_master_ae.c | 80 +- .../sources/ble/ll/ll_main_conn_slave.c | 35 +- .../controller/sources/ble/ll/ll_main_diag.c | 39 +- .../controller/sources/ble/ll/ll_main_dtm.c | 65 +- .../sources/ble/ll/ll_main_enc_master.c | 35 +- .../sources/ble/ll/ll_main_enc_slave.c | 41 +- .../controller/sources/ble/ll/ll_main_iso.c | 278 +++ .../controller/sources/ble/ll/ll_main_past.c | 37 +- .../controller/sources/ble/ll/ll_main_pc.c | 101 + .../controller/sources/ble/ll/ll_main_phy.c | 40 +- .../controller/sources/ble/ll/ll_main_priv.c | 76 +- .../controller/sources/ble/ll/ll_main_sc.c | 37 +- .../stack/controller/sources/ble/ll/ll_math.c | 97 +- .../controller/sources/ble/lmgr/lmgr_events.c | 41 +- .../controller/sources/ble/lmgr/lmgr_main.c | 70 +- .../ble/lmgr/lmgr_main_adv_master_ae.c | 45 +- .../sources/ble/lmgr/lmgr_main_adv_slave_ae.c | 41 +- .../sources/ble/lmgr/lmgr_main_cis_master.c | 60 + .../sources/ble/lmgr/lmgr_main_conn.c | 37 +- .../sources/ble/lmgr/lmgr_main_iso.c | 52 + .../sources/ble/lmgr/lmgr_main_master.c | 37 +- .../sources/ble/lmgr/lmgr_main_priv.c | 37 +- .../sources/ble/lmgr/lmgr_main_sc.c | 37 +- .../sources/ble/lmgr/lmgr_main_slave.c | 46 +- .../controller/sources/ble/sch/sch_ble.c | 154 +- .../controller/sources/ble/sch/sch_int_rm.h | 51 +- .../controller/sources/ble/sch/sch_int_tm.h | 88 + .../stack/controller/sources/ble/sch/sch_rm.c | 381 ++-- .../stack/controller/sources/ble/sch/sch_tm.c | 352 ++++ .../controller/sources/common/bb/bb_int.h | 36 +- .../controller/sources/common/bb/bb_main.c | 189 +- .../controller/sources/common/chci/chci_tr.c | 203 +- .../controller/sources/common/sch/sch_int.h | 82 +- .../controller/sources/common/sch/sch_list.c | 307 ++- .../controller/sources/common/sch/sch_main.c | 278 +-- .../components/boards/arduino_primo.h | 2 +- .../nordic-bsp/components/boards/boards.c | 3 +- .../nordic-bsp/components/boards/boards.h | 4 +- .../nordic-bsp/components/boards/nrf6310.h | 2 +- .../nordic-bsp/components/boards/pca10000.h | 2 +- .../nordic-bsp/components/boards/pca10001.h | 2 +- .../nordic-bsp/components/boards/pca10003.h | 2 +- .../nordic-bsp/components/boards/pca10028.h | 2 +- .../nordic-bsp/components/boards/pca10031.h | 2 +- .../nordic-bsp/components/boards/pca10036.h | 2 +- .../nordic-bsp/components/boards/pca10040.h | 2 +- .../nordic-bsp/components/boards/pca10056.h | 2 +- .../nordic-bsp/components/boards/pca10059.h | 2 +- .../nordic-bsp/components/boards/pca10100.h | 155 ++ .../nordic-bsp/components/boards/pca20006.h | 2 +- .../nordic-bsp/components/boards/pca20020.h | 2 +- .../nordic-bsp/components/boards/wt51822.h | 2 +- .../stack/thirdparty/uecc/uECC.c | 2 +- .../stack/thirdparty/uecc/uECC_ll.c | 2 +- .../stack/thirdparty/uecc/uECC_ll.h | 6 +- 356 files changed, 38476 insertions(+), 8862 deletions(-) create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_sniffer_api.h delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_defs.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_slave.c rename features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/{bb_ble_test.c => bb_ble_dtm.c} (80%) create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_sniffer.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_acad.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_master.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_slave.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_master.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_slave.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_iso.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_pc.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_master.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_slave.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_iso.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_master.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_slave.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_master.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_slave.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_iso.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_pc.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso_data.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_bis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_pc.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_ext.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_slave.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_pc.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_cis_master.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_iso.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_tm.h create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_tm.c create mode 100644 features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10100.h diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api.h index 81b273d9c8c..a9011674c9f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief BLE baseband interface file. + * \file + * + * \brief BLE baseband interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -167,8 +168,6 @@ typedef struct /*! * \brief Initialize the BLE BB. * - * \return None. - * * Initialize baseband resources. */ /*************************************************************************************************/ @@ -178,8 +177,6 @@ void BbBleInit(void); /*! * \brief Initialize for scanning master operations. * - * \return None. - * * Update the operation table with scanning master operations routines. */ /*************************************************************************************************/ @@ -189,8 +186,6 @@ void BbBleScanMasterInit(void); /*! * \brief Initialize for auxiliary scanning master operations. * - * \return None. - * * Update the operation table with auxiliary scanning master operations routines. */ /*************************************************************************************************/ @@ -200,8 +195,6 @@ void BbBleAuxScanMasterInit(void); /*! * \brief Initialize for periodic scanning master operations. * - * \return None. - * * Update the operation table with periodic scanning master operations routines. */ /*************************************************************************************************/ @@ -211,8 +204,6 @@ void BbBlePerScanMasterInit(void); /*! * \brief Initialize for connectable master operations. * - * \return None. - * * Update the operation table with connectable master operations routines. */ /*************************************************************************************************/ @@ -222,8 +213,6 @@ void BbBleConnMasterInit(void); /*! * \brief Initialize for advertising slave operations. * - * \return None. - * * Update the operation table with advertising slave operations routines. */ /*************************************************************************************************/ @@ -233,8 +222,6 @@ void BbBleAdvSlaveInit(void); /*! * \brief Initialize for auxiliary advertising slave operations. * - * \return None. - * * Update the operation table with auxiliary advertising slave operations routines. */ /*************************************************************************************************/ @@ -244,8 +231,6 @@ void BbBleAuxAdvSlaveInit(void); /*! * \brief Initialize for connectable slave operations. * - * \return None. - * * Update the operation table with connectable slave operations routines. */ /*************************************************************************************************/ @@ -255,8 +240,6 @@ void BbBleConnSlaveInit(void); /*! * \brief Initialize for test operations. * - * \return None. - * * Update the operation table with test operations routines. */ /*************************************************************************************************/ @@ -318,8 +301,6 @@ uint16_t BbBleInitPeriodicList(uint8_t numEntries, uint8_t *pFreeMem, uint32_t f * \brief Get advertising packet statistics. * * \param pStats Advertising statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAdvStats(BbBleAdvPktStats_t *pStats); @@ -329,8 +310,6 @@ void BbBleGetAdvStats(BbBleAdvPktStats_t *pStats); * \brief Get scan packet statistics. * * \param pStats Scan statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetScanStats(BbBleScanPktStats_t *pStats); @@ -340,8 +319,6 @@ void BbBleGetScanStats(BbBleScanPktStats_t *pStats); * \brief Get auxiliary advertising packet statistics. * * \param pStats Auxiliary advertising statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAuxAdvStats(BbBleAuxAdvPktStats_t *pStats); @@ -351,8 +328,6 @@ void BbBleGetAuxAdvStats(BbBleAuxAdvPktStats_t *pStats); * \brief Get auxiliary scan packet statistics. * * \param pStats Auxiliary scan statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAuxScanStats(BbBleAuxScanPktStats_t *pStats); @@ -362,8 +337,6 @@ void BbBleGetAuxScanStats(BbBleAuxScanPktStats_t *pStats); * \brief Get periodic scan packet statistics. * * \param pStats Periodic scan statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetPerScanStats(BbBlePerScanPktStats_t *pStats); @@ -373,8 +346,6 @@ void BbBleGetPerScanStats(BbBlePerScanPktStats_t *pStats); * \brief Get connection packet statistics. * * \param pStats Connection data statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetConnStats(BbBleDataPktStats_t *pStats); @@ -384,8 +355,6 @@ void BbBleGetConnStats(BbBleDataPktStats_t *pStats); * \brief Get test mode packet statistics. * * \param pStats Test data statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetTestStats(BbBleDataPktStats_t *pStats); @@ -395,8 +364,6 @@ void BbBleGetTestStats(BbBleDataPktStats_t *pStats); * \brief Get PDU filter statistics. * * \param pStats PDU filter statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetPduFiltStats(BbBlePduFiltStats_t *pStats); @@ -405,8 +372,6 @@ void BbBleGetPduFiltStats(BbBlePduFiltStats_t *pStats); /*! * \brief Initialize for connected isochronous stream master operations. * - * \return None. - * * Update the operation table with CIS master operations routines. */ /*************************************************************************************************/ @@ -416,20 +381,34 @@ void BbBleCisMasterInit(void); /*! * \brief Initialize for connected isochronous stream slave operations. * - * \return None. - * * Update the operation table with CIS slave operations routines. */ /*************************************************************************************************/ void BbBleCisSlaveInit(void); +/*************************************************************************************************/ +/*! + * \brief Initialize for Broadcast isochronous stream master operations. + * + * Update the operation table with CIS master operations routines. + */ +/*************************************************************************************************/ +void BbBleBisMasterInit(void); + +/*************************************************************************************************/ +/*! + * \brief Initialize for Broadcast isochronous stream slave operations. + * + * Update the operation table with CIS slave operations routines. + */ +/*************************************************************************************************/ +void BbBleBisSlaveInit(void); + /*************************************************************************************************/ /*! * \brief Get CIS packet statistics. * * \param pStats CIS data statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetCisStats(BbBleDataPktStats_t *pStats); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_op.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_op.h index 874a1eb05fb..1f0c57907f9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_op.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_op.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief BLE baseband interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief BLE baseband interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -41,7 +42,7 @@ extern "C" { **************************************************************************************************/ /*! \brief Convert BLE protocol ticks to BB ticks. */ -#define BB_BLE_TO_BB_TICKS(n) BB_US_TO_BB_TICKS((n) * LL_BLE_US_PER_TICK) +#define BB_BLE_TO_US(n) ((n) * LL_BLE_US_PER_TICK) /*! \brief Increment statistics counter. */ #define BB_INC_STAT(s) s++ @@ -51,7 +52,7 @@ extern "C" { **************************************************************************************************/ /*! \brief Operation types. */ -enum +typedef enum { BB_BLE_OP_TEST_TX, /*!< Continuous Tx test mode. */ BB_BLE_OP_TEST_RX, /*!< Continuous Rx test mode. */ @@ -65,14 +66,16 @@ enum BB_BLE_OP_MST_PER_SCAN_EVENT, /*!< Master periodic scanning event. */ BB_BLE_OP_MST_CIS_EVENT, /*!< Master CIS event. */ BB_BLE_OP_SLV_CIS_EVENT, /*!< Slave CIS event. */ + BB_BLE_OP_MST_BIS_EVENT, /*!< Master BIS event. */ + BB_BLE_OP_SLV_BIS_EVENT, /*!< Slave BIS event. */ BB_BLE_OP_NUM /*!< Total number of operations. */ -}; +} BbBleOp_t; /*! \brief Maximum request PDU length (MAX(LL_SCAN_REQ_PDU_LEN, LL_CONN_IND_PDU_LEN)). */ #define BB_REQ_PDU_MAX_LEN (LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN) -/*! \brief Guard time at the end of a scan window to the next BOD. Backoff one advertise data exchange. */ -#define BB_SCAN_GUARD_US (LL_ADV_PKT_MAX_USEC + LL_BLE_TIFS_US + \ +/*! \brief Minimum scan time to cover one advertise data exchange. */ +#define BB_MIN_SCAN_US (LL_ADV_PKT_MAX_USEC + LL_BLE_TIFS_US + \ LL_SCAN_REQ_MAX_USEC + LL_BLE_TIFS_US + \ LL_SCAN_RSP_MAX_USEC + \ BbGetSchSetupDelayUs()) @@ -157,7 +160,7 @@ typedef struct int8_t advRssi; /*!< RSSI of advertisement. */ uint8_t advRxPhyOptions; /*!< Rx PHY options. */ uint32_t advCrc; /*!< CRC of advertisement. */ - uint32_t advStartTs; /*!< Start of advertising packet timestamp. */ + uint32_t advStartTsUsec; /*!< Start of advertising packet timestamp in microseconds. */ uint32_t elapsedUsec; /*!< Elapsed time of a single scan window in microseconds. */ /* Filter results. */ @@ -187,7 +190,7 @@ typedef struct uint8_t advChMap; /*!< Advertising channel map. */ /* Return parameters. */ - uint32_t reqStartTs; /*!< Start of request packet timestamp. */ + uint32_t reqStartTsUsec; /*!< Start of request packet timestamp in microseconds. */ /* Filter results. */ bbBlePduFiltResults_t filtResults; /*!< Results from PDU filtering. */ @@ -212,7 +215,7 @@ typedef struct int8_t auxAdvRssi; /*!< RSSI of advertisement. */ uint8_t auxRxPhyOptions; /*!< Rx PHY options. */ uint32_t auxAdvCrc; /*!< CRC of advertisement. */ - uint32_t auxStartTs; /*!< Start of auxiliary advertising packet timestamp. */ + uint32_t auxStartTsUsec; /*!< Start of auxiliary advertising packet timestamp in microseconds. */ /* Filter results. */ bbBlePduFiltResults_t filtResults; /*!< Results from PDU filtering. */ @@ -230,9 +233,8 @@ typedef struct int8_t perAdvRssi; /*!< RSSI of advertisement. */ uint8_t perRxPhyOptions; /*!< Rx PHY options. */ uint32_t perAdvCrc; /*!< CRC of advertisement. */ - uint32_t perStartTs; /*!< Start of periodic advertising packet timestamp. */ + uint32_t perStartTsUsec; /*!< Start of periodic advertising packet timestamp in microseconds. */ bool_t perIsFirstTs; /*!< True if it is the first timestamp for a serial of periodic packets. */ - } BbBleMstPerScanEvent_t; /*! \brief Slave auxiliary advertising event operation data (\ref BB_BLE_OP_SLV_AUX_ADV_EVENT). */ @@ -252,7 +254,7 @@ typedef struct /* Return parameters. */ uint8_t auxRxPhyOptions; /*!< Rx PHY options. */ - uint32_t auxReqStartTs; /*!< Start of request packet timestamp. */ + uint32_t auxReqStartTsUsec; /*!< Start of request packet timestamp in microseconds. */ /* Filter results. */ bbBlePduFiltResults_t filtResults; /*!< Results from PDU filtering. */ @@ -281,7 +283,7 @@ typedef struct BbBleRxDataComp_t rxDataCback; /*!< Receive completion callback. */ /* Return parameters. */ - uint32_t startTs; /*!< Start timestamp of the first received packet. */ + uint32_t startTsUsec; /*!< Start timestamp of the first received packet in microseconds. */ int8_t rssi; /*!< RSSI of the last received packet. */ uint8_t rxPhyOptions; /*!< Rx PHY options. */ } BbBleSlvConnEvent_t; @@ -313,12 +315,35 @@ typedef struct BbBleRxDataComp_t rxDataCback; /*!< Receive completion callback. */ /* Return parameters. */ - uint32_t startTs; /*!< Start timestamp of the first received packet. */ + bool_t isFirstTs; /*!< True for the first timestamp. */ + uint32_t startTsUsec; /*!< Start timestamp of the first received packet in microseconds. */ + uint32_t rxTsUsec; /*!< Timestamp of the received packet. in microseconds */ int8_t rssi; /*!< RSSI of the last received packet. */ uint8_t rxPhyOptions; /*!< Rx PHY options. */ uint32_t rxSyncDelayUsec; /*!< Receive timeout in microseconds. */ } BbBleSlvCisEvent_t; +/*! \brief BIS master event operation data (\ref BB_BLE_OP_MST_BIS_EVENT). */ +typedef struct +{ + uint32_t rxSyncDelayUsec; /*!< Receive timeout in microseconds. */ + BbBleExec_t execCback; /*!< Execute callback. */ + BbBleRxDataComp_t rxDataCback; /*!< Recieve completion callback. */ + + /* Return parameters. */ + uint32_t startTsUsec; /*!< First Rx timestamp. */ +} BbBleMstBisEvent_t; + +/*! \brief BIS slave event operation data (\ref BB_BLE_OP_SLV_BIS_EVENT). */ +typedef struct +{ + BbBleExec_t execCback; /*!< Execute callback. */ + BbBleTxDataComp_t txDataCback; /*!< Transmit completion callback. */ + + /* Return parameters. */ + /* None */ +} BbBleSlvBisEvent_t; + /*! \brief Continuous transmit operation data (\ref BB_BLE_OP_TEST_TX). */ typedef struct { @@ -357,6 +382,8 @@ typedef struct BbBleData_tag BbBleMstPerScanEvent_t mstPerScan; /*!< Master periodic scanning event data. */ BbBleMstCisEvent_t mstCis; /*!< Master CIS event data. */ BbBleSlvCisEvent_t slvCis; /*!< Slave CIS event data. */ + BbBleMstBisEvent_t mstBis; /*!< Master BIS event data. */ + BbBleSlvBisEvent_t slvBis; /*!< Slave BIS event data. */ BbBleTestTx_t testTx; /*!< Transmit test data. */ BbBleTestRx_t testRx; /*!< Receive test data. */ } op; /*!< Operation specific data. */ @@ -373,8 +400,6 @@ typedef struct BbBleData_tag * \param descs Array of transmit buffer descriptor. * \param cnt Number of descriptors. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleSlvConnEvent_t::rxDataCback callback routine. */ @@ -388,8 +413,6 @@ void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt); * \param pBuf Receive data buffer. * \param len Maximum length of data buffer. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleSlvConnEvent_t::rxDataCback callback routine. * @@ -406,8 +429,6 @@ void BbBleRxData(uint8_t *pBuf, uint16_t len); * \param descs Array of transmit buffer descriptor. * \param cnt Number of descriptors. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleMstCisEvent_t::rxDataCback or \ref BbBleSlvCisEvent_t::rxDataCback * callback routine. @@ -422,8 +443,6 @@ void BbBleCisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt); * \param pBuf Receive data buffer. * \param len Maximum length of data buffer. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleSlvCisEvent_t::rxDataCback callback routine. * @@ -432,6 +451,45 @@ void BbBleCisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt); */ /*************************************************************************************************/ void BbBleCisRxData(uint8_t *pBuf, uint16_t len); + +/*************************************************************************************************/ +/*! + * \brief Transmit BIS Data PDU at next transmit slot. + * + * \param descs Array of transmit buffer descriptor. + * \param cnt Number of descriptors. + * \param nextPduTime Next PDU time. + * \param pNextChan Next PDU channel. + */ +/*************************************************************************************************/ +void BbBleBisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt, uint32_t nextPduTime, PalBbBleChan_t *pNextChan); + +/*************************************************************************************************/ +/*! + * \brief Set receive BIS Data PDU buffer for next receive slot. + * + * \param pBuf Receive data buffer. + * \param len Maximum length of data buffer. + * \param nextPduTime Next PDU time. + * \param pNextChan Next PDU channel. + * \param reAcq Rx train re-acquisition required. + */ +/*************************************************************************************************/ +void BbBleBisRxData(uint8_t *pBuf, uint16_t len, uint32_t nextPduTime, PalBbBleChan_t *pNextChan, bool_t reAcq); + +/*************************************************************************************************/ +/*! + * \brief Receive data re-acquisition. + * + * \param syncTime Due time for the next Rx operation. + * \param pChan Channel parameters. + * + * Update due time for next Rx operation. Called after a missed Rx operation for re-acquisition + * of the receive train. + */ +/*************************************************************************************************/ +void BbBleBisRxDataReAcq(uint32_t syncTime, PalBbBleChan_t *pChan); + /*! \} */ /* BB_API_BLE */ #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_pdufilt.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_pdufilt.h index 6654bc2e461..7b1cdd93b9b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_pdufilt.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_pdufilt.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief BLE baseband PDU filtering interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief BLE baseband PDU filtering interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -143,8 +144,6 @@ bool_t BbBleExtPduFiltCheck(const bbBlePduExtFiltParams_t *pExtFiltParams, * \param pFiltResults Filter results. * \param pPeerIdAddr Storage for peer ID address. * \param pPeerIdAddrType Storage for peer ID address type; - * - * \return None. */ /*************************************************************************************************/ static inline void BbBlePduFiltResultsGetPeerIdAddr(const bbBlePduFiltResults_t *pFiltResults, uint64_t *pPeerIdAddr, uint8_t *pPeerIdAddrType) @@ -166,8 +165,6 @@ static inline void BbBlePduFiltResultsGetPeerIdAddr(const bbBlePduFiltResults_t * * \param pFiltResults Filter results. * \param pPeerRpa Storage for peer RPA or 0. - * - * \return None. */ /*************************************************************************************************/ static inline void BbBlePduFiltResultsGetPeerRpa(const bbBlePduFiltResults_t *pFiltResults, uint64_t *pPeerRpa) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_periodiclist.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_periodiclist.h index 2b4283873b1..dcc7096eff5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_periodiclist.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_periodiclist.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief BLE baseband periodiclist interface file. + * \file + * + * \brief BLE baseband periodiclist interface file. + * + * Copyright (c) 2016-2017 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -65,8 +66,6 @@ uint8_t BbBlePeriodicListGetSize(void); /*! * \brief Clear all periodic list entries. * - * \return None. - * * Clear all periodic list entries stored in the BB. * * \note No resource synchronization is required to modify the periodic list resource as diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_reslist.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_reslist.h index 6ddf9e66dd0..7b0ae093f5a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_reslist.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_reslist.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief BLE baseband resolving list interface file. + * \file + * + * \brief BLE baseband resolving list interface file. + * + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -69,8 +70,6 @@ typedef void (*bbBleResListAddrResNeeded_t)(uint64_t rpa, bool_t peer, uint8_t p * \brief Set address resolution needed callback. * * \param cback Callback. - * - * \return None. */ /*************************************************************************************************/ void BbBleResListSetAddrResNeededCback(bbBleResListAddrResNeeded_t cback); @@ -90,8 +89,6 @@ uint8_t BbBleResListGetSize(void); /*! * \brief Clear resolving list. * - * \return None. - * * Clear all resolving list entries stored in the BB. */ /*************************************************************************************************/ @@ -331,8 +328,6 @@ uint8_t BbBleResListLocalStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr); /*! * \brief Handle timeout of local resolvable addresses. * - * \return None. - * * A new local resolvable address will be generated for each entry in the resolving list. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_whitelist.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_whitelist.h index 70aed1437f6..420e8d5d816 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_whitelist.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_api_whitelist.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief BLE baseband whitelist interface file. + * \file + * + * \brief BLE baseband whitelist interface file. + * + * Copyright (c) 2016-2017 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -64,8 +65,6 @@ uint8_t BbBleWhiteListGetSize(void); /*! * \brief Clear all white list entries. * - * \return None. - * * Clear all white list entries stored in the BB. * * \note No resource synchronization is required to modify the white list resource as @@ -111,8 +110,6 @@ bool_t BbBleWhiteListRemove(bool_t randAddr, uint64_t addr); /*************************************************************************************************/ /*! * \brief Add anonymous device to the white list. - * - * \return None. */ /*************************************************************************************************/ void BbBleWhiteListAddAnonymous(void); @@ -120,8 +117,6 @@ void BbBleWhiteListAddAnonymous(void); /*************************************************************************************************/ /*! * \brief Remove anonymous device from the white list. - * - * \return None. */ /*************************************************************************************************/ void BbBleWhiteListRemoveAnonymous(void); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_sniffer_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_sniffer_api.h new file mode 100644 index 00000000000..007cfe8842d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/bb_ble_sniffer_api.h @@ -0,0 +1,163 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Packet sniffer interface file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef BB_BLE_SNIFFER_API_H +#define BB_BLE_SNIFFER_API_H + +#include "wsf_types.h" +#include "bb_api.h" +#include "pal_bb_ble.h" +#include "ll_defs.h" +#include "bb_ble_api.h" + +#ifndef BB_SNIFFER_ENABLED +/*! \brief Sniffer enabled for controller */ +#define BB_SNIFFER_ENABLED FALSE +#endif + +#ifdef __cplusplus +extern "C" { +#endif +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Maximum number of buffer. */ +#define BB_SNIFFER_MAX_NUM_BUF 20 + +/*! \brief Max packet size for a sniffer packet. */ +#define BB_SNIFFER_MAX_PKT_SIZE 28 + +/*! \brief Output methods of sniffer. */ +enum +{ + BB_SNIFFER_OUTPUT_HCI_TOKEN, /*!< Output over HCI through tokens. */ + BB_SNIFFER_OUTPUT_TOTAL_METHODS, /*!< Total output methods. */ + + BB_SNIFFER_OUTPUT_NULL_METHOD /*!< Null output method. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Sniffer Packet types (Used to parse packet for sniffer). */ +enum +{ + BB_SNIFF_PKT_TYPE_TX, /*!< Transmit packets. */ + BB_SNIFF_PKT_TYPE_RX /*!< Receive packets. */ +}; + +/*! \brief Sniffer packet metadata. */ +typedef struct +{ + uint8_t type; /*!< TX/RX. */ + uint8_t status; /*!< TX/RX status. */ + uint8_t state; /*!< State of the operation. */ + uint32_t timeStamp; /*!< Timestamp. */ + uint8_t rssi; /*!< Signal power (TxPower, or RSSI). */ + PalBbBleChan_t chan; /*!< channelization params. */ +} BbBleSnifferMeta_t; + +/*! \brief Sniffer data packet. */ +typedef struct +{ + BbBleSnifferMeta_t meta; /*!< Metadata header. */ + uint8_t hdr[LL_DATA_HDR_MAX_LEN]; /*!< Header raw data. */ +} BbBleDataSniffPkt_t; + +/*! \brief Sniffer advertisement packet. */ +typedef struct +{ + BbBleSnifferMeta_t meta; /*!< Metadata header. */ + uint8_t hdr[LL_ADV_HDR_LEN]; /*!< Header raw data. */ +} BbBleAdvSniffPkt_t; + +/*! \brief Sniffer generic packet. */ +typedef struct +{ + union + { + BbBleSnifferMeta_t meta; /*!< Metadata. */ + BbBleDataSniffPkt_t dataPkt; /*!< Data packet. */ + BbBleAdvSniffPkt_t advPkt; /*!< Advertising packet. */ + } pktType; /*!< Packet type. */ +} BbBleSnifferPkt_t; + +/*! \brief Sniffer output call signature. */ +typedef void (*bbSnifferFn_t)(BbBleSnifferPkt_t *pPkt); + +/*! \brief Sniffer get packet call signature. */ +typedef BbBleSnifferPkt_t* (*bbSnifferGetPktFn_t)(void); + +/*! \brief HCI output context. */ +typedef struct +{ + uint16_t bufIdx; /*!< Current packet buffer index. */ + BbBleSnifferPkt_t pktBuf[BB_SNIFFER_MAX_NUM_BUF]; /*!< Sotrage for packet buffer. */ +} BbBleSnifferHciCtx_t; + +/*! \brief Sniffer context. */ +typedef struct +{ + /* Control variables. */ + bool_t enabled; /*!< Enable status of sniffer. */ + bbSnifferGetPktFn_t snifferGetPktFn; /*!< Sniffer get packet function callback. */ + bbSnifferFn_t snifferOutCb; /*!< Sniffer output callback. */ + uint32_t packetCtr; /*!< Number of packets processed. */ + + /* Temporary storage. */ + uint8_t txBuf[LL_DATA_HDR_MAX_LEN]; /*!< Temporary storage for conn tx buf. */ + uint8_t chanIdx; /*!< Temporary storage for adv channel index. */ + + /* Output contexts. */ + union + { + BbBleSnifferHciCtx_t hci; /*!< HCI Output context. */ + } outputCtx; /*!< Output context union. */ +} bbSnifferCtx_t; + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +extern bbSnifferCtx_t bbSnifferCtx; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +uint8_t BbBleInitSniffer(uint8_t outMethod, bool_t enable); +void bbBleSnifferMstScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t *pPktData); +void bbBleSnifferMstAuxScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t *pPktData); +void bbBleSnifferSlvAdvPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData); +void bbBleSnifferSlvAuxAdvPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData); +void bbBleSnifferMstPerScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t *pPktData); +void bbBleSnifferConnPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData); + +#ifdef __cplusplus +}; +#endif + +#endif /* BB_BLE_TESTER_API_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/lhci_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/lhci_api.h index 26b00eb431b..72eb718416b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/lhci_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/lhci_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer HCI subsystem API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer HCI subsystem API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -46,6 +47,9 @@ typedef struct /*! \brief Command handler call signature. */ typedef bool_t (*lhciCmdHandler_t)(LhciHdr_t *pHdr, uint8_t *pBuf); +/*! \brief Event complete handler call signature. */ +typedef void (*lhciCompHandler_t)(void); + /************************************************************************************************** Function Declarations **************************************************************************************************/ @@ -68,16 +72,19 @@ void LhciPastInit(void); void LhciChannelSelection2Init(void); void LhciCisMasterInit(void); void LhciCisSlaveInit(void); +void LhciBisSlaveInit(void); +void LhciBisMasterInit(void); void LhciIsoInit(void); +void LhciPowerControlInit(void); void LhciVsExtInit(lhciCmdHandler_t decodeCmd); void LhciHandlerInit(wsfHandlerId_t handlerId); void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); void LhciIsoHandlerInit(wsfHandlerId_t handlerId); void LhciIsoHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); -void LhciSetDefaultHciSupCmd(uint8_t *pBuf); #if (LL_ENABLE_TESTER) void LhciTesterInit(void); #endif +void LhciInitFinalize(void); /* Command processing */ uint8_t LhciPackCmdStatusEvt(uint8_t *pBuf, uint8_t status, uint16_t opCode); @@ -87,8 +94,10 @@ uint8_t LhciPackVsEvt(uint8_t *pBuf, uint16_t vsEvtCode); void LhciSendEvent(uint8_t *pBuf); bool_t LhciIsEventPending(void); uint8_t LhciPackEvtHdr(uint8_t *pBuf, uint8_t evtCode, uint8_t paramLen); +bool_t LhciSnifferHandler(void); /* Event processing */ +void LhciRegisterSendTrCompleteHandler(lhciCompHandler_t compCback); bool_t LhciVsEncodeTraceMsgEvtPkt(const uint8_t *pBuf, uint32_t len); #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_api.h index e0c255a0c83..c677bd4e007 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,14 +36,14 @@ extern "C" { #endif /*! \brief Version number. */ -#define LL_VER_NUM 0x1302 /* Default value. Auto-generated by builder. */ +#define LL_VER_NUM 1366 /************************************************************************************************** Data Types **************************************************************************************************/ /*! \brief The following status values are used in the LL API. */ -enum +typedef enum { LL_SUCCESS = 0x00, LL_ERROR_CODE_UNKNOWN_HCI_CMD = 0x01, @@ -114,7 +115,7 @@ enum LL_ERROR_CODE_LIMIT_REACHED = 0x43, LL_ERROR_CODE_OP_CANCELLED_BY_HOST = 0x44, LL_ERROR_CODE_PKT_TOO_LONG = 0x45 -}; +} LlStatus_t; /*! \addtogroup LL_API_INIT * \{ */ @@ -147,13 +148,15 @@ typedef struct /* ISO */ uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */ uint8_t numIsoRxBuf; /*!< Default number of ISO receive buffers. */ - uint16_t maxIsoBufLen; /*!< Maximum ISO buffer size between host and controller. */ - uint16_t maxIsoPduLen; /*!< Maximum ISO PDU buffer size. */ - + uint16_t maxIsoSduLen; /*!< Maximum ISO SDU size between host and controller. */ + uint16_t maxIsoPduLen; /*!< Maximum ISO Data PDU buffer size. */ /* CIS */ uint8_t maxCig; /*!< Maximum number of CIG. */ - uint8_t maxCis; /*!< Maximum number of CIS. */ - uint16_t subEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */ + uint8_t maxCis; /*!< Maximum number of CIS, it is shared by the CIGs. */ + uint16_t cisSubEvtSpaceDelay; /*!< Subevent spacing above T_MSS in microsecond. */ + /* BIS */ + uint8_t maxBig; /*!< Maximum number of BIG. */ + uint8_t maxBis; /*!< Maximum number of BIS. */ /* DTM */ uint16_t dtmRxSyncMs; /*!< DTM Rx synchronization window in milliseconds. */ /* PHY */ @@ -246,20 +249,26 @@ typedef struct #define LL_FEAT_PAST_RECIPIENT (UINT64_C(1) << 25) /*!< Periodic Advertising Sync Transfer – Recipient supported. */ #define LL_FEAT_SCA_UPDATE (UINT64_C(1) << 26) /*!< Sleep Clock Accuracy Updates supported. */ #define LL_FEAT_REMOTE_PUB_KEY_VALIDATION (UINT64_C(1) << 27) /*!< Remote Public Key Validation supported. */ -/* --- Core Spec Milan --- */ +/* --- Core Spec 5.2 --- */ #define LL_FEAT_CIS_MASTER_ROLE (UINT64_C(1) << 28) /*!< Connected Isochronous Stream Master Role supported. */ #define LL_FEAT_CIS_SLAVE_ROLE (UINT64_C(1) << 29) /*!< Connected Isochronous Stream Slave Role supported. */ #define LL_FEAT_ISO_BROADCASTER (UINT64_C(1) << 30) /*!< Isochronous Broadcaster Role supported. */ #define LL_FEAT_ISO_SYNC (UINT64_C(1) << 31) /*!< Isochronous Synchronizer Role supported. */ +#define LL_FEAT_ISO_HOST_SUPPORT (UINT64_C(1) << 32) /*!< Host support for ISO Channels. */ +#define LL_FEAT_POWER_CONTROL_REQUEST (UINT64_C(1) << 33) /*!< Power control requests supported. */ +#define LL_FEAT_POWER_CHANGE_IND (UINT64_C(1) << 34) /*!< Power control power change indication supported. */ +#define LL_FEAT_PATH_LOSS_MONITOR (UINT64_C(1) << 35) /*!< Path loss monitoring supported. */ -#define LL_FEAT_ALL_MASK (UINT64_C(0xFF01FFFF))/*!< All feature mask, need to be updated when new features are added. */ +#define LL_HOST_CONTROLLED_FEAT LL_FEAT_ISO_HOST_SUPPORT /*!< Feature bits controlled by the host. */ + +#define LL_FEAT_ALL_MASK (UINT64_C(0x0000000FFF01FFFF)) /*!< All feature mask, need to be updated when new features are added. */ /*! \brief This parameter identifies the device role. */ -enum +typedef enum { LL_ROLE_MASTER = 0, /*!< Role is master. */ LL_ROLE_SLAVE = 1 /*!< Role is slave. */ -}; +} LlRole_t; /*! \brief Operational mode flags. */ enum @@ -280,6 +289,7 @@ enum LL_OP_MODE_FLAG_ENA_MST_CIS_NULL_PDU = (1 << 12), /*!< Enable CIS master sends additional NULL PDU for acknowledge scheme. */ LL_OP_MODE_FLAG_ENA_SLV_AUX_IND_ADVA = (1 << 13), /*!< AdvA will be included in AUX_ADV_IND instead of ADV_EXT_IND. */ LL_OP_MODE_FLAG_ENA_ADV_CHAN_RAND = (1 << 14), /*!< Enable advertising channel randomization. */ + LL_OP_MODE_DISABLE_POWER_MONITOR = (1 << 15), /*!< Disable power monitoring. */ /* diagnostics only */ LL_OP_MODE_FLAG_ENA_ADV_DLY = (1 << 16), /*!< Enable advertising delay. */ LL_OP_MODE_FLAG_ENA_SCAN_BACKOFF = (1 << 17), /*!< Enable scan backoff. */ @@ -359,7 +369,7 @@ typedef struct uint8_t priAdvChanMap; /*!< Primary Advertising Channel Map. */ uint8_t ownAddrType; /*!< Own Address Type. */ uint8_t peerAddrType; /*!< Peer Address Type. */ - uint8_t *pPeerAddr; /*!< Peer Address. */ + const uint8_t *pPeerAddr; /*!< Peer Address. */ uint8_t advFiltPolicy; /*!< Advertising Filter Policy. */ int8_t advTxPwr; /*!< Advertising Tx Power. */ uint8_t priAdvPhy; /*!< Primary Advertising PHY. */ @@ -523,7 +533,7 @@ enum LL_PHYS_LE_CODED_BIT = (1 << 2), /*!< LE Coded PHY. */ }; -/*! \brief All PHYs preference. */ +/*! \brief All PHYs preference. */ enum { LL_ALL_PHY_ALL_PREFERENCES = 0, /*!< All PHY preferences. */ @@ -540,14 +550,41 @@ enum }; /*! \brief PHY types. */ +typedef enum +{ + LL_PHY_NONE = 0, /*!< PHY not selected. */ + LL_PHY_LE_1M = 1, /*!< LE 1M PHY. */ + LL_PHY_LE_2M = 2, /*!< LE 2M PHY. */ + LL_PHY_LE_CODED = 3, /*!< LE Coded PHY. */ +} LlPhy_t; + +/*! \brief Power Control managed PHYs. */ enum { - LL_PHY_NONE = 0, /*!< PHY not selected. */ - LL_PHY_LE_1M = 1, /*!< LE 1M PHY. */ - LL_PHY_LE_2M = 2, /*!< LE 2M PHY. */ - LL_PHY_LE_CODED = 3 /*!< LE Coded PHY. */ + LL_PC_PHY_1M = 1, + LL_PC_PHY_2M = 2, + LL_PC_PHY_CODED_S8 = 3, + LL_PC_PHY_CODED_S2 = 4, + + LL_PC_PHY_TOTAL = LL_PC_PHY_CODED_S2, + LL_PC_PHY_INVALID = 0xFF }; +/*! \brief Power control PHY bits. */ +enum +{ + LL_PC_1M_BIT = (1 << 0), /*!< LE 1M PHY bit. */ + LL_PC_2M_BIT = (1 << 1), /*!< LE 2M PHY bit. */ + LL_PC_CODED_S8_BIT = (1 << 2), /*!< LE Coded S8 PHY bit. */ + LL_PC_CODED_S2_BIT = (1 << 3), /*!< LE Coded S2 PHY bit. */ + LL_PC_MAX_BIT = LL_PC_CODED_S2_BIT, + + LL_PC_ALL_BITS = LL_PC_1M_BIT | LL_PC_2M_BIT | LL_PC_CODED_S8_BIT | LL_PC_CODED_S8_BIT +}; + +/*! \brief PCL path loss monitoring unused high threshold value. */ +#define LL_PC_PATH_LOSS_UNUSED_HIGH_THRESHOLD 0xFF + /*! \brief Privacy modes. */ enum { @@ -610,95 +647,170 @@ enum /*! \} */ /* LL_API_CONN */ - /*! \addtogroup LL_API_ISO * \{ */ /*! \brief Packing scheme. */ -enum +typedef enum { - LL_PACKING_SEQUENTIAL = 0, /*!< Sequential. */ - LL_PACKING_INTERLEAVED = 1 /*!< Interleaved. */ -}; - -/*! \brief Framing. */ -enum -{ - LL_FRAMING_UNFRAMED = 0, /*!< Unframed. */ - LL_FRAMING_FRAMED = 1, /*!< Framed. */ -}; + LL_PACKING_SEQUENTIAL = 0, /*!< Sequential. */ + LL_PACKING_INTERLEAVED = 1 /*!< Interleaved. */ +} LlPacking_t; /*! \brief CIS parameters. */ typedef struct { - uint8_t cisId; /*!< Used to identify a connected isochronous stream. */ - uint16_t sduSizeMToS; /*!< Maximum size of a data SDU from the master to the slave. */ - uint16_t sduSizeSToM; /*!< Maximum size of a data SDU from the slave to the master. */ - uint8_t phyMToS; /*!< PHY to be used for transmission from master to slave. */ - uint8_t phySToM; /*!< PHY to be used for transmission from master to slave. */ - uint16_t transLatMToS; /*!< Maximum time in microseconds between the transmissions of a Data PDU from the Link Layer of the master to the reception of the same Data PDU in the Link Layer of the slave. */ - uint16_t transLatSToM; /*!< Maximum time in microseconds between the transmissions of a Data PDU from the Link Layer of the slave to the reception of the same Data PDU in the Link Layer of the master. */ - uint8_t rteMToS; /*!< Maximum number of times every PDU should be retransmitted from the master to slave. */ - uint8_t rteSToM; /*!< Maximum number of times every PDU should be retransmitted from the slave to master. */ + uint8_t cisId; /*!< Used to identify a connected isochronous stream. */ + uint16_t sduSizeMToS; /*!< Maximum size of a data SDU from the master to the slave. */ + uint16_t sduSizeSToM; /*!< Maximum size of a data SDU from the slave to the master. */ + uint8_t phyMToS; /*!< PHY to be used for transmission from master to slave. */ + uint8_t phySToM; /*!< PHY to be used for transmission from master to slave. */ + uint8_t rteMToS; /*!< Maximum number of times every PDU should be retransmitted from the master to slave. */ + uint8_t rteSToM; /*!< Maximum number of times every PDU should be retransmitted from the slave to master. */ } LlCisCisParams_t; /*! \brief CIG parameters. */ typedef struct { - uint8_t cigId; /*!< Used to identify the connected isochronous group. */ - uint32_t sduIntervalMToS; /*!< The time interval between the start of consecutive SDUs from the master Host */ - uint32_t sduIntervalSToM; /*!< The time interval between the start of consecutive SDUs from the slave Host */ - uint8_t sca; /*!< Sleep clock accuracy. */ - uint8_t packing; /*!< Packing scheme. */ - uint8_t framing; /*!< Indicates the format of CIS Data PDUs. */ - uint8_t numCis; /*!< Number of CIS to set. */ - LlCisCisParams_t *pCisParam; /*!< CIS parameters. */ + uint8_t cigId; /*!< Used to identify the connected isochronous group. */ + uint32_t sduIntervalMToS; /*!< The time interval between the start of consecutive SDUs from the master Host. */ + uint32_t sduIntervalSToM; /*!< The time interval between the start of consecutive SDUs from the slave Host. */ + uint8_t sca; /*!< Sleep clock accuracy. */ + uint8_t packing; /*!< Packing scheme. */ + LlFraming_t framing:8; /*!< Indicates the format of CIS Data PDUs. */ + uint16_t transLatMToS; /*!< Maximum time in microseconds between the transmissions of a Data PDU from the Link Layer of the master to the reception of the same Data PDU in the Link Layer of the slave. */ + uint16_t transLatSToM; /*!< Maximum time in microseconds between the transmissions of a Data PDU from the Link Layer of the slave to the reception of the same Data PDU in the Link Layer of the master. */ + uint8_t numCis; /*!< Number of CIS to set. */ + LlCisCisParams_t *pCisParam; /*!< CIS parameters. */ } LlCisCigParams_t; /*! \brief CIG test CIS parameters. */ typedef struct { - uint8_t cisId; /*!< CIS identifier. */ - uint8_t nse; /*!< Maximum number of subevent in each interval on CIS. */ - uint8_t plSizeMToS; /*!< Maximum size of payload from master to slave. */ - uint8_t plSizeSToM; /*!< Maximum size of payload from slave to master. */ - uint8_t phyMToS; /*!< Master to slave PHY. */ - uint8_t phySToM; /*!< Slave to master PHY. */ - uint8_t ftMToS; /*!< Master to slave flush time. */ - uint8_t ftSToM; /*!< Slave to master flush time. */ - uint8_t bnMToS; /*!< Master to slave burst number. */ - uint8_t bnSToM; /*!< Slave to master burst number. */ + uint8_t cisId; /*!< CIS identifier. */ + uint8_t nse; /*!< Maximum number of subevent in each interval on CIS. */ + uint16_t sduSizeMToS; /*!< Maximum size of a data SDU from the master to the slave. */ + uint16_t sduSizeSToM; /*!< Maximum size of a data SDU from the slave to the master. */ + uint16_t pduSizeMToS; /*!< Maximum size of payload from master to slave. */ + uint16_t pduSizeSToM; /*!< Maximum size of payload from slave to master. */ + uint8_t phyMToS; /*!< Master to slave PHY. */ + uint8_t phySToM; /*!< Slave to master PHY. */ + uint8_t bnMToS; /*!< Master to slave burst number. */ + uint8_t bnSToM; /*!< Slave to master burst number. */ } LlCisCigCisParamsTest_t; /*! \brief CIG test CIG parameters. */ typedef struct { - uint8_t cigId; /*!< CIG identifier. */ - uint16_t isoInterval; /*!< The time duration of the isochronous PDU interval. */ - uint8_t numCis; /*!< Number of CIS. */ - uint8_t sca; /*!< Sleep clock accuracy. */ - uint8_t packing; /*!< Packing scheme. */ - LlCisCigCisParamsTest_t *pCisParam; /*!< CIS parameters. */ + uint8_t cigId; /*!< CIG identifier. */ + uint32_t sduIntervalMToS; /*!< The time interval between the start of consecutive SDUs from the master Host. */ + uint32_t sduIntervalSToM; /*!< The time interval between the start of consecutive SDUs from the slave Host. */ + uint8_t ftMToS; /*!< The flush timeout in multiples of ISO_Interval for each payload sent from the master to slave. */ + uint8_t ftSToM; /*!< The flush timeout in multiples of ISO_Interval for each payload sent from the slave to master. */ + uint16_t isoInterval; /*!< The time duration of the isochronous PDU interval. */ + uint8_t sca; /*!< Sleep clock accuracy. */ + uint8_t packing; /*!< Packing scheme. */ + LlFraming_t framing:8; /*!< Indicates the format of CIS Data PDUs. */ + uint8_t numCis; /*!< Number of CIS. */ + LlCisCigCisParamsTest_t *pCisParam; /*!< CIS parameters. */ } LlCisCigParamsTest_t; -/*! \brief CIS create CIS parameters. */ +/*! \brief Create CIS parameters. */ typedef struct { - uint16_t *pCisHandle; /*!< Pointer to the connected isochronous stream handle array. */ + uint16_t *pCisHandle; /*!< Pointer to the connected isochronous handle array. */ uint16_t *pAclHandle; /*!< Pointer to the asynchronous connection link handle array. */ } LlCisCreateCisParams_t; -/*! \brief CIS create CIS parameters. */ +/*! \brief ISO data path direction. */ +typedef enum +{ + LL_ISO_DATA_DIR_INPUT = 0x00, /*!< Input data path. */ + LL_ISO_DATA_DIR_OUTPUT = 0x01 /*!< Output data path. */ +} LlIsoDataPathDir_t; + +/*! \brief ISO data path. */ +typedef enum +{ + LL_ISO_DATA_PATH_HCI = 0x00, + LL_ISO_DATA_PATH_VS = 0x01, /*!< Vendor Specific. */ + + LL_ISO_DATA_PATH_TOTAL, /*!< Total number of data path methods. */ + + LL_ISO_DATA_PATH_DISABLED = 0xFF, /*!< Data path is disabled. */ +} LlIsoDataPath_t; + +/*! \brief ISO data path direction bit. */ +enum +{ + LL_ISO_DATA_PATH_INPUT_BIT = (1 << 0), /*!< Data path input bit. */ + LL_ISO_DATA_PATH_OUTPUT_BIT = (1 << 1) /*!< Data path output bit. */ +}; + +/*! \brief LE setup ISO Data Path command. */ +typedef struct +{ + uint16_t handle; /*!< Handle of CIS or BIS. */ + LlIsoDataPathDir_t dpDir:8; /*!< Data path direction. */ + uint8_t dpId; /*!< Data path ID. */ + uint8_t codecFormat; /*!< Codec Format. */ + uint16_t codecCompId; /*!< Codec Company ID. */ + uint16_t codecId; /*!< Codec ID. */ + uint32_t ctrDly; /*!< Codec ID. */ + uint8_t codecConfigLen; /*!< Codec configuration length. */ + uint8_t *pCodecConfig; /*!< Codec configuration. */ +} LlIsoSetupDataPath_t; + +/*! \brief BIG Create BIG message. */ +typedef struct +{ + uint8_t bigHandle; /*!< Used to identify the BIG. */ + uint8_t advHandle; /*!< Used to identify the periodic advertising train. */ + uint8_t numBis; /*!< Total number of BISes in the BIG. */ + uint32_t sduInterUsec; /*!< Interval, in microseconds, of BIG SDUs. */ + uint16_t maxSdu; /*!< Maximum size of an SDU. */ + uint16_t mtlMs; /*!< Maximum time in milliseconds. */ + uint8_t rtn; /*!< Retransmitted number. */ + uint8_t phys; /*!< Transmitter PHYs of packets. */ + uint8_t packing; /*!< Sequential or Interleaved packing. */ + LlFraming_t framing:8; /*!< Unframed or Framed. */ + uint8_t encrypt; /*!< Unencrypted or Encrypted. */ + uint8_t bcstCode[LL_BC_LEN];/*!< Session key used to encrypt and decrypt BIS payloads. */ +} LlCreateBig_t; + +/*! \brief BIG Create BIG Test message. */ typedef struct { - uint16_t isoHandle; /*!< Handle of CIS or BIS. */ - uint32_t inputBw; /*!< Input bandwidth. */ - uint32_t outputBw; /*!< Output bandwidth. */ - uint8_t inputDataPath; /*!< Input data path. */ - uint8_t outputDataPath; /*!< Output data path. */ - uint8_t inputMaxPayloadSize; /*!< Input maximum payload size. */ - uint8_t outputMaxPayloadSize; /*!< Output maximum payload size. */ -} LlIsoSetupDataPathParams_t; + uint8_t bigHandle; /*!< Used to identify the BIG. */ + uint8_t advHandle; /*!< Used to identify the periodic advertising train. */ + uint8_t numBis; /*!< Total number of BISes in the BIG. */ + uint32_t sduInterUsec; /*!< Interval in microseconds of BIG SDUs. */ + uint16_t isoInter; /*!< Duration of an isochronous interval for BIG PDUs in 1.25ms unit. */ + uint8_t nse; /*!< Total number of subevents in each interval of each BIS in the BIG. */ + uint16_t maxSdu; /*!< Maximum size of a SDU. */ + uint16_t maxPdu; /*!< Maximum size of payload. */ + uint8_t phys; /*!< Transmitter PHYs of packets. */ + uint8_t packing; /*!< Sequential or Interleaved packing. */ + LlFraming_t framing:8; /*!< Unframed or Framed. */ + uint8_t bn; /*!< Number of new payloads in each interval for each BIS. */ + uint8_t irc; /*!< Number of times the scheduled payload(s) are transmitted in a given event. */ + uint8_t pto; /*!< Offset used for pre-transmissions. */ + uint8_t encrypt; /*!< Unencrypted or Encrypted. */ + uint8_t bcstCode[LL_BC_LEN];/*!< Code used to derive the session key. */ +} LlCreateBigTest_t; + +/*! \brief BIG Create Sync message. */ +typedef struct +{ + uint8_t bigHandle; /*!< Used to identify the BIG. */ + uint16_t syncHandle; /*!< Periodic advertising train handle. */ + uint8_t encrypt; /*!< Unencrypted or Encrypted. */ + uint8_t bcstCode[LL_BC_LEN];/*!< Session key code for encrypt and decrypt BIS payloads. */ + uint8_t mse; /*!< Maximum number of subevents. */ + uint16_t bigSyncTimeout; /*!< Synchronization timeout for the BIS, in the units of 10ms. */ + uint8_t numBis; /*!< Total number of BISes in the BIG. */ + uint8_t bis[LL_MAX_BIS]; /*!< List of indices of BISes. */ +} LlBigCreateSync_t; /*! \} */ /* LL_API_ISO */ @@ -763,6 +875,35 @@ typedef struct uint16_t numRxTimeout; /*!< Receive timeout count. */ } LlTestReport_t; +/*! \brief ISO test packet payload type. */ +typedef enum +{ + LL_ISO_PLD_TYPE_ZERO_LEN = 0x00, /*!< Zero length payload. */ + LL_ISO_PLD_TYPE_VAR_LEN = 0x01, /*!< Variable length payload. */ + LL_ISO_PLD_TYPE_MAX_LEN = 0x02 /*!< Maximum length payload. */ +} LlIsoPldType_t; + +/*! \brief ISO test counter data. */ +typedef struct +{ + uint32_t numSuccess; /*!< Received good packet count. */ + uint32_t numMissed; /*!< Received missed packet count. */ + uint32_t numFailed; /*!< Received failed packet count. */ +} LlIsoTestCtrs_t; + +/*! \brief ISO link quality statistics. */ +typedef struct +{ + uint32_t txUnAckPkt; /*!< Unacked packets. */ + uint32_t txFlushedPkt; /*!< Flushed packets. */ + uint32_t txLastSubEventPkt; /*!< The CIS slave transmit CIS Data PDU on it's last subevent. */ + uint32_t retransmitPkt; /*!< Retransmitted packets. */ + uint32_t crcErrPkt; /*!< CRC error packets. */ + uint32_t rxUnreceivedPkt; /*!< Packets unreceived by flush point. */ + uint32_t duplicatePkt; /*!< Retransmitted CIS data PDUs. */ +} LlIsoLinkQual_t; + + /*! \} */ /* LL_API_TEST */ /*! \addtogroup LL_API_EVENT @@ -813,10 +954,19 @@ enum LL_CONN_IQ_REPORT_IND, /*!< LE connection IQ report received. */ LL_CTE_REQ_FAILED_IND, /*!< LE CTE request failed received. */ LL_PER_SYNC_TRSF_RCVD_IND, /*!< LE periodic advertising sync transfer received. */ - /* --- Core Spec Milan --- */ + /* --- Core Spec 5.2 --- */ LL_CIS_EST_IND, /*!< CIS established event. */ LL_CIS_REQ_IND, /*!< CIS request event. */ + LL_CREATE_BIG_CNF, /*!< Create BIG complete. */ + LL_TERM_BIG_IND, /*!< Terminate BIG complete. */ + LL_BIG_TERM_SYNC_CNF, /*!< BIG Terminate Sync complete. */ + LL_BIG_SYNC_EST_IND, /*!< BIG sync established event. */ + LL_BIG_SYNC_LOST_IND, /*!< BIG sync lost event. */ LL_REQ_PEER_SCA_IND, /*!< Request peer SCA complete. */ + LL_TX_POWER_REPORTING_IND, /*!< LL txPower change report received. */ + LL_PATH_LOSS_REPORTING_IND, /*!< Path loss reporting event. */ + LL_ISO_EVT_CMPL_IND, /*!< ISO Event complete event. */ + LL_BIG_INFO_ADV_REPORT_IND /*!< BIG Info advertising report event. */ }; /*! \brief Advertising report indication */ @@ -1031,29 +1181,6 @@ typedef struct uint8_t handle; /*!< Advertising handle. */ } LlPerAdvEnableCnf_t; -/********************** CIS ******************************/ -/*! \brief CIS established event */ -typedef struct -{ - wsfMsgHdr_t hdr; /*!< Event header. */ - uint8_t status; /*!< Status. */ - uint16_t cisHandle; /*!< CIS handle. */ - uint32_t cigSyncDelayUsec; /*!< CIG synchronization delay in usec. */ - uint32_t cisSyncDelayUsec; /*!< CIS synchronization delay in usec. */ - uint8_t phyMToS; /*!< Master to slave PHY. */ - uint8_t phySToM; /*!< Slave to master PHY. */ -} LlCisEstInd_t; - -/*! \brief CIS request event */ -typedef struct -{ - wsfMsgHdr_t hdr; /*!< Event header. */ - uint16_t aclHandle; /*!< ACL handle. */ - uint16_t cisHandle; /*!< ACL handle. */ - uint8_t cigId; /*!< CIG identifier. */ - uint8_t cisId; /*!< CIS identifier. */ -} LlCisReqInd_t; - /*! \brief Extended advertising report event types. */ enum { @@ -1181,6 +1308,98 @@ typedef struct uint8_t advClkAccuracy; /*!< Advertiser clock accuracy. */ } LlPerSyncTrsfRcvdInd_t; +/*! \brief CIS established event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t status; /*!< Status. */ + uint16_t cisHandle; /*!< CIS handle. */ + uint32_t cigSyncDelayUsec; /*!< CIG synchronization delay in usec. */ + uint32_t cisSyncDelayUsec; /*!< CIS synchronization delay in usec. */ + uint32_t transLatUsecMToS; /*!< The maximum time, in microseconds, for transmission of SDUs of all CISes from master to slave. */ + uint32_t transLatUsecSToM; /*!< The maximum time, in microseconds, for transmission of SDUs of all CISes from slave to master. */ + uint8_t phyMToS; /*!< Master to slave PHY. */ + uint8_t phySToM; /*!< Slave to master PHY. */ + uint8_t nse; /*!< Number of subevents. */ + uint8_t bnMToS; /*!< Burst number master to slave. */ + uint8_t bnSToM; /*!< Burst number slave to master. */ + uint8_t ftMToS; /*!< Flush timeout master to slave. */ + uint8_t ftSToM; /*!< Flush timeout slave to master. */ + uint16_t maxPduMToS; /*!< Max pdu master to slave. */ + uint16_t maxPduSToM; /*!< Max pdu slave to master. */ + uint16_t isoInterval; /*!< Time between two consecutive ISO anchor points. */ +} LlCisEstInd_t; + +/*! \brief CIS request event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint16_t aclHandle; /*!< ACL handle. */ + uint16_t cisHandle; /*!< ACL handle. */ + uint8_t cigId; /*!< CIG identifier. */ + uint8_t cisId; /*!< CIS identifier. */ +} LlCisReqInd_t; + +/*! \brief Create BIG complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t status; /*!< Status. */ + uint8_t bigHandle; /*!< BIG handle. */ + uint32_t syncDelayUsec; /*!< Synchronization delay in microseconds. */ + uint32_t transLatUsec; /*!< Transport latency, in microseconds. */ + uint8_t phy; /*!< Transmit PHY. */ + uint8_t nse; /*!< Number of Sub-Events in each BIS event in the BIG. */ + uint8_t bn; /*!< Number of new payloads in each BIS event. */ + uint8_t pto; /*!< Offset used for pre-transmissions. */ + uint8_t irc; /*!< Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< Maximum size of the payload. */ + uint16_t isoInterval; /*!< Time between two consecutive ISO anchor points. */ + uint8_t numBis; /*!< Number of BIS. */ + uint16_t bisHandle[LL_MAX_BIS]; /*!< Connection handles of the BIS's. */ +} LlCreateBigCnf_t; + +/*! \brief Terminate BIG complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t bigHandle; /*!< BIG handle. */ + uint8_t reason; /*!< Terminate reason. */ +} LlTerminateBigInd_t; + +/*! \brief BIG Terminate complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t status; /*!< Status. */ + uint8_t bigHandle; /*!< BIG handle. */ +} LlBigTermSyncCnf_t; + +/*! \brief Create BIG complete (Sync Established) event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t status; /*!< Status. */ + uint8_t bigHandle; /*!< BIG handle. */ + uint32_t transLatUsec; /*!< The maximum time, in microseconds, for transmission of SDUs of all BISes. */ + uint8_t nse; /*!< Number of Sub-Events in each BIS event in the BIG. */ + uint8_t bn; /*!< Number of new payloads in each BIS event. */ + uint8_t pto; /*!< Offset used for pre-transmissions. */ + uint8_t irc; /*!< Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< Maximum size of the payload. */ + uint16_t isoInterval; /*!< Time between two consecutive ISO anchor points. */ + uint8_t numBis; /*!< Number of BIS. */ + uint16_t bisHandle[LL_MAX_BIS]; /*!< Connection handles of the BIS's. */ +} LlBigSyncEstInd_t; + +/*! \brief BIG sync lost event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t bigHandle; /*!< BIG handle. */ + uint8_t reason; /*!< Sync lost reason. */ +} LlBigSyncLostInd_t; + /*! \brief LE request peer SCA complete */ typedef struct { @@ -1190,6 +1409,55 @@ typedef struct uint8_t peerSca; /*!< Peer SCA. */ } LlPeerScaCnf_t; +/*! \brief LE power reporting indication. */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t status; /*!< Status. */ + uint16_t connHandle; /*!< Connection handle. */ + uint8_t reason; /*!< Report reason. */ + uint8_t phy; /*!< PHY. */ + int8_t txPower; /*!< txPower. */ + uint8_t txPowerLimits; /*!< Transmit power level limit flags. */ + int8_t delta; /*!< Change from previous txPower. */ +} LlPowerReportInd_t; + +/*! \brief VS ISO Event complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint8_t handle; /*!< ISO handle. */ + uint32_t evtCtr; /*!< Event counter. */ +} LlIsoEventCmplInd_t; + +/*! \brief BIG Info Advertising Report event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint16_t syncHandle; /*!< Sync handle identifying the periodic advertising train. */ + uint8_t numBis; /*!< Number of BIS. */ + uint8_t nse; /*!< Number of Sub-Events in each BIS event in the BIG. */ + uint16_t isoInterv; /*!< ISO interval. */ + uint8_t bn; /*!< Number of new payloads in each BIS event. */ + uint8_t pto; /*!< Offset used for pre-transmissions. */ + uint8_t irc; /*!< Number of times a payload is transmitted in a BIS event. */ + uint16_t maxPdu; /*!< Maximum size of the PDU. */ + uint32_t sduInterv; /*!< SDU interval. */ + uint16_t maxSdu; /*!< Maximum size of the SDU. */ + LlPhy_t phy; /*!< Transmit PHY. */ + LlFraming_t framing; /*!< Framing mode. */ + bool_t encrypt; /*!< Encryption enabled. */ +} LlBigInfoAdvRptInd_t; + +/*! \brief LE Path loss reporting event. */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< Event header. */ + uint16_t connHandle; /*!< Connection handle. */ + uint8_t curPathLoss; /*!< Current path loss. */ + uint8_t zoneEntered; /*!< Zone entered. */ +} LlPathLossThresholdEvt_t; + /*! \brief Union of all event types */ typedef union { @@ -1229,10 +1497,19 @@ typedef union LlPerAdvSyncLostInd_t perAdvSyncLostInd; /*!< LE periodic advertising sync lost. */ /* --- Core Spec 5.1 --- */ LlPerSyncTrsfRcvdInd_t perASyncTrsfRcvdInd; /*!< LE periodic advertising sync transfer received. */ - /* --- Core Spec Milan --- */ - LlCisEstInd_t cisEst; /*!< LE CIS established. */ - LlCisReqInd_t cisReq; /*!< LE CIS request. */ + /* --- Core Spec 5.2 --- */ + LlCisEstInd_t cisEstInd; /*!< LE CIS established. */ + LlCisReqInd_t cisReqInd; /*!< LE CIS request. */ + LlCreateBigCnf_t createBigCnf; /*!< LE create BIG complete. */ + LlTerminateBigInd_t termBigInd; /*!< LE terminate BIG complete. */ + LlBigTermSyncCnf_t bigTermSyncCnf; /*!< LE BIG terminate sync. */ + LlBigSyncEstInd_t bigSyncEstInd; /*!< LE BIG sync established. */ + LlBigSyncLostInd_t bigSyncLostInd; /*!< LE BIG sync lost. */ LlPeerScaCnf_t peerScaCnf; /*!< LE request peer SCA complete. */ + LlPowerReportInd_t powerRptInd; /*!< LE transmit power reporting indication. */ + LlIsoEventCmplInd_t isoEvtCmplInd; /*!< VS ISO Event complete. */ + LlBigInfoAdvRptInd_t bigInfoInd; /*!< LE Big Info indication. */ + LlPathLossThresholdEvt_t pathLossEvt; /*!< LE Path loss threshold reporting event. */ } LlEvt_t; /*! \brief Event callback */ @@ -1242,7 +1519,7 @@ typedef bool_t (*llEvtCback_t)(LlEvt_t *pEvent); typedef void (*llAclCback_t)(uint16_t handle, uint8_t numBufs); /*! \brief ISO callback */ -typedef void (*llIsoCback_t)(uint16_t handle, uint8_t numBufs); +typedef void (*llIsoCback_t)(uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts); /*! \} */ /* LL_API_EVENT */ @@ -1259,8 +1536,6 @@ typedef void (*llIsoCback_t)(uint16_t handle, uint8_t numBufs); * * \param pCfg Pointer to runtime configuration parameters. * - * \return None. - * * This function returns default value for the LL subsystem's runtime configurations. */ /*************************************************************************************************/ @@ -1272,8 +1547,6 @@ void LlGetDefaultRunTimeCfg(LlRtCfg_t *pCfg); * * \param pCfg Pointer to runtime configuration parameters (data must be static). * - * \return None. - * * This function initializes the LL subsystem's runtime configuration. * * \note This routine must be called only once before any other initialization routines. @@ -1336,8 +1609,6 @@ uint16_t LlInitExtScanMem(uint8_t *pFreeMem, uint32_t freeMemSize); /*! * \brief Initialize LL subsystem for operation as an advertising slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising slave. */ /*************************************************************************************************/ @@ -1347,8 +1618,6 @@ void LlAdvSlaveInit(void); /*! * \brief Initialize LL subsystem for operation for extended advertising slave. * - * \return None. - * * This function initializes the LL subsystem for use as an extended advertising slave. */ /*************************************************************************************************/ @@ -1358,8 +1627,6 @@ void LlExtAdvSlaveInit(void); /*! * \brief Initialize LL subsystem for operation as a connectable slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and connectable slave. */ /*************************************************************************************************/ @@ -1369,8 +1636,6 @@ void LlConnSlaveInit(void); /*! * \brief Initialize LL subsystem for operation as a encryptable connectable slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and encryptable * connectable slave. */ @@ -1381,8 +1646,6 @@ void LlEncConnSlaveInit(void); /*! * \brief Initialize LL subsystem for operation as a scanning master. * - * \return None. - * * This function initializes the LL subsystem for use as a scanning master. */ /*************************************************************************************************/ @@ -1392,8 +1655,6 @@ void LlScanMasterInit(void); /*! * \brief Initialize LL subsystem for operation for extended scanning master. * - * \return None. - * * This function initializes the LL subsystem for use as an extended scanning master. */ /*************************************************************************************************/ @@ -1403,8 +1664,6 @@ void LlExtScanMasterInit(void); /*! * \brief Initialize LL subsystem for operation as an initiating master. * - * \return None. - * * This function initializes the LL subsystem for use as an initiating master. */ /*************************************************************************************************/ @@ -1414,8 +1673,6 @@ void LlInitMasterInit(void); /*! * \brief Initialize LL subsystem for operation as an extended initiating master. * - * \return None. - * * This function initializes the LL subsystem for use as an initiating master. */ /*************************************************************************************************/ @@ -1425,8 +1682,6 @@ void LlExtInitMasterInit(void); /*! * \brief Initialize LL subsystem for operation as a connectable master. * - * \return None. - * * This function initializes the LL subsystem for use as a scanning and initiating master. */ /*************************************************************************************************/ @@ -1436,8 +1691,6 @@ void LlConnMasterInit(void); /*! * \brief Initialize LL subsystem for operation as a encryptable connectable slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and encryptable * connectable slave. */ @@ -1448,8 +1701,6 @@ void LlEncConnMasterInit(void); /*! * \brief Initialize LL subsystem for operation with privacy. * - * \return None. - * * This function initializes the LL subsystem for use with privacy. */ /*************************************************************************************************/ @@ -1459,8 +1710,6 @@ void LlPrivInit(void); /*! * \brief Initialize LL subsystem for secure connections. * - * \return None. - * * This function initializes the LL subsystem for secure connections. */ /*************************************************************************************************/ @@ -1470,8 +1719,6 @@ void LlScInit(void); /*! * \brief Initialize LL subsystem for PHY features (slave). * - * \return None. - * * This function initializes the LL subsystem for slave PHY features. */ /*************************************************************************************************/ @@ -1481,8 +1728,6 @@ void LlPhySlaveInit(void); /*! * \brief Initialize LL subsystem for PHY features (master). * - * \return None. - * * This function initializes the LL subsystem for master PHY features. */ /*************************************************************************************************/ @@ -1492,8 +1737,6 @@ void LlPhyMasterInit(void); /*! * \brief Initialize LL subsystem for secure connections. * - * \return None. - * * This function initializes the LL subsystem for secure connections. */ /*************************************************************************************************/ @@ -1503,8 +1746,6 @@ void LlChannelSelection2Init(void); /*! * \brief Initialize LL subsystem for test modes. * - * \return None. - * * This function initializes the LL subsystem for test modes. */ /*************************************************************************************************/ @@ -1516,22 +1757,27 @@ void LlTestInit(void); * * \param handlerId WSF handler ID. * - * \return None. - * * This function initializes the LL subsystem. It is called once upon system initialization. * It must be called before any other function in the LL API is called. */ /*************************************************************************************************/ void LlHandlerInit(wsfHandlerId_t handlerId); +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for power control. + * + * This function initializes the LL subsystem for power control. + */ +/*************************************************************************************************/ +void LlPowerControlInit(void); + /*************************************************************************************************/ /*! * \brief LL message dispatch handler. * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); @@ -1540,8 +1786,6 @@ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); /*! * \brief Reset LL subsystem. * - * \return None. - * * Reset the LL subsystem. All active connections are closed and all radio procedures such as * scanning or advertising are terminated. */ @@ -1554,8 +1798,6 @@ void LlReset(void); * * \param evtCback Client callback function. * - * \return None. - * * This function is called by a client to register for LL events. */ /*************************************************************************************************/ @@ -1568,8 +1810,6 @@ void LlEvtRegister(llEvtCback_t evtCback); * \param sendCompCback Client ACL send complete callback function. * \param recvPendCback Client ACL receive pending callback function. * - * \return None. - * * This function is called by a client to register for ACL data. */ /*************************************************************************************************/ @@ -1579,15 +1819,13 @@ void LlAclRegister(llAclCback_t sendCompCback, llAclCback_t recvPendCback); /*! * \brief Register ISO handler. * - * \param sendCompCback Client ISO send complete callback function. - * \param recvPendCback Client ISO receive pending callback function. - * - * \return None. + * \param sendIsoCompCback Client ISO send complete callback function. + * \param recvIsoPendCback Client ISO receive pending callback function. * * This function is called by a client to register for ISO data. */ /*************************************************************************************************/ -void LlIsoRegister(llIsoCback_t sendCompCback, llIsoCback_t recvPendCback); +void LlIsoRegister(llIsoCback_t sendIsoCompCback, llIsoCback_t recvIsoPendCback); /*! \} */ /* LL_API_INIT */ @@ -1600,8 +1838,6 @@ void LlIsoRegister(llIsoCback_t sendCompCback, llIsoCback_t recvPendCback); * * \param pAddr Bluetooth device address. * - * \return None. - * * Set the BD address to be used by LL. */ /*************************************************************************************************/ @@ -1613,8 +1849,6 @@ void LlSetBdAddr(const uint8_t *pAddr); * * \param pAddr Bluetooth device address. * - * \return None. - * * Get the BD address currently used by LL or all zeros if address is not set. */ /*************************************************************************************************/ @@ -1653,8 +1887,6 @@ uint8_t LlGetRandAddr(uint8_t *pAddr); * \param pCompId Company ID. * \param pBtVer Bluetooth version. * \param pImplRev Implementation revision. - * - * \return None. */ /*************************************************************************************************/ void LlGetVersion(uint16_t *pCompId, uint8_t *pBtVer, uint16_t *pImplRev); @@ -1665,8 +1897,6 @@ void LlGetVersion(uint16_t *pCompId, uint8_t *pBtVer, uint16_t *pImplRev); * * \param pStates Supported states bitmask. * - * \return None. - * * Return the states supported by the LL. */ /*************************************************************************************************/ @@ -1678,8 +1908,6 @@ void LlGetSupStates(uint8_t *pStates); * * \param pFeatures Supported features bitmask. * - * \return None. - * * Return the LE features supported by the LL. */ /*************************************************************************************************/ @@ -1701,6 +1929,21 @@ void LlGetFeatures(uint8_t *pFeatures); /*************************************************************************************************/ uint8_t LlSetFeatures(const uint8_t *pFeatures); +/*************************************************************************************************/ +/*! + * \brief Set host feature. + * + * \param bitNum Bit position in the FeatureSet. + * \param bitVal Enable or disable feature. + * + * \return Status error code. + * + * Set or clear a bit in the feature controlled by the Host in the Link Layer FeatureSet + * stored in the Controller. + */ +/*************************************************************************************************/ +uint8_t LlSetHostFeatures(uint8_t bitNum, bool_t bitVal); + /*************************************************************************************************/ /*! * \brief Get random number. @@ -1986,22 +2229,6 @@ uint8_t LlSetValidatePublicKeyMode(uint8_t validateMode); /*************************************************************************************************/ uint8_t LlSetChannelClass(const uint8_t *pChanMap); -/*************************************************************************************************/ -/*! - * \brief Set HCI supported command - * - * \param byte Byte location of command - * \param bit Bit location of command - * \param enable Enable or disable command - * - * \return Status error code - * - * This will not set a command to supported if it is not actually supported by the device. - * It will only "emulate" non-support of supported commands. - */ -/*************************************************************************************************/ -uint8_t LlSetHciSupCmd(uint8_t byte, uint8_t bit, bool_t enable); - /*************************************************************************************************/ /*! * \brief Set operational mode flags. @@ -2022,8 +2249,6 @@ uint8_t LlSetOpFlags(uint32_t flags, bool_t enable); * * \param phyOptions PHY options. * - * \return None. - * * Set the default TX PHY options for extended adv slave primary and secondary channel. */ /*************************************************************************************************/ @@ -2040,8 +2265,6 @@ void LlSetDefaultExtAdvTxPhyOptions(const uint8_t phyOptions); * * \param advTxPwr Advertising transmit power level. * - * \return None. - * * Set the advertising transmit power. */ /*************************************************************************************************/ @@ -2117,8 +2340,6 @@ uint8_t LlSetScanRespData(uint8_t len, const uint8_t *pData); * \brief Advertising enable. * * \param enable Set to TRUE to enable advertising, FALSE to disable advertising. - * - * \return None. * Enable or disable advertising. */ @@ -2239,8 +2460,6 @@ uint8_t LlSetExtScanRespData(uint8_t handle, uint8_t op, uint8_t fragPref, uint8 * \param numAdvSets Number of elements in enaParam[]. * \param enaParam Enable parameter table. * - * \return None. - * * Enable or disable extended advertising. */ /*************************************************************************************************/ @@ -2393,8 +2612,6 @@ uint8_t LlSetExtAdvTxPhyOptions(uint8_t handle, uint8_t priPhyOpts, uint8_t secP * \param pMinTxPwr Return buffer for minimum transmit power. * \param pMaxTxPwr Return buffer for maximum transmit power. * - * \return None. - * * Read the minimum and maximum transmit powers supported by the LL. */ /*************************************************************************************************/ @@ -2407,8 +2624,6 @@ void LlReadSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr); * \param pTxPathComp Return buffer for RF transmit path compensation value. * \param pRxPathComp Return buffer for RF receive path compensation value. * - * \return None. - * * Read the RF Path Compensation Values parameter used in the Tx Power Level and RSSI calculation. */ /*************************************************************************************************/ @@ -2435,8 +2650,6 @@ uint8_t LlWriteRfPathComp(int16_t txPathComp, int16_t rxPathComp); * * \param enable Set to TRUE to enable scan reports, FALSE to disable scan reports. * - * \return None. - * * Enable or disable reports about the scanners from which an advertiser receives scan requests. */ /*************************************************************************************************/ @@ -2484,8 +2697,6 @@ uint8_t LlSetScanParam(const LlScanParam_t *pParam); * \param enable Set to TRUE to enable scanning, FALSE to disable scanning. * \param filterDup Set to TRUE to filter duplicates. * - * \return None. - * * Enable or disable scanning. This function is only used when operating in master role. */ /*************************************************************************************************/ @@ -2516,8 +2727,6 @@ uint8_t LlSetExtScanParam(uint8_t ownAddrType, uint8_t scanFiltPolicy, uint8_t s * \param duration Duration. * \param period Period. * - * \return None. - * * Enable or disable extended scanning. */ /*************************************************************************************************/ @@ -2628,8 +2837,6 @@ uint8_t LlSetPeriodicAdvRcvEnable(uint16_t syncHandle, uint8_t enable); /*! * \brief Initialize LL subsystem for PAST(Periodic advertising sync transfer). * - * \return None. - * * This function initializes the LL subsystem for PAST(Periodic advertising sync transfer). */ /*************************************************************************************************/ @@ -2789,17 +2996,42 @@ uint8_t LlGetTxPowerLevel(uint16_t handle, uint8_t type, int8_t *pLevel); /*************************************************************************************************/ /*! - * \brief Set connection's TX power level. + * \brief Get connection's enhanced TX power level and max txPower. + * + * \param handle Connection handle. + * \param phy PHY. + * \param pCurPwr Transmit power level. + * \param pMaxPwr Max power level. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlGetEnhTxPowerLevel(uint16_t handle, uint8_t phy, int8_t *pCurPwr, int8_t *pMaxPwr); + +/*************************************************************************************************/ +/*! + * \brief Set connection's TX power level (all PHYs). * * \param handle Connection handle. * \param level Transmit power level. * * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetAllPhyTxPowerLevel(uint16_t handle, int8_t level); + +/*************************************************************************************************/ +/*! + * \brief Set connection's TX power level for a PHY. * - * Set the TX power of a connection. + * \param handle Connection handle. + * \param level Transmit power level. + * \param phy PHY txPower to change. + * + * \return Status error code. */ /*************************************************************************************************/ -uint8_t LlSetTxPowerLevel(uint16_t handle, int8_t level); +uint8_t LlSetPhyTxPowerLevel(uint16_t handle, int8_t level, uint8_t phy); /*************************************************************************************************/ /*! @@ -2836,7 +3068,7 @@ uint8_t LlRemoteConnParamReqReply(uint16_t handle, const LlConnSpec_t *pConnSpec * \param handle Connection handle. * \param reason Reason code. * - * \return None. + * \return Status error code. * * Negative reply to a connection parameter request. */ @@ -2894,8 +3126,6 @@ uint8_t LlSetDataLen(uint16_t handle, uint16_t txLen, uint16_t txTime); * \param pMaxTxLen Maximum number of payload bytes for a Data PDU * \param pMaxTxTime Maximum microseconds for a Data PDU * - * \return None. - * * Suggested length and microseconds that the local Controller should use to transmit a * single Link Layer Data Channel PDU. */ @@ -2926,8 +3156,6 @@ uint8_t LlWriteDefaultDataLen(uint16_t maxTxLen, uint16_t maxTxTime); * \param pMaxRxLen Maximum number of payload bytes for a Rx Data PDU * \param pMaxRxTime Maximum microseconds for a Rx Data PDU * - * \return None. - * * Read the Controller's maximum supported payload octets and packet duration times for * transmission and reception. */ @@ -2965,6 +3193,18 @@ uint8_t LlReadPhy(uint16_t handle, uint8_t *pTxPhy, uint8_t *pRxPhy); /*************************************************************************************************/ uint8_t LlSetDefaultPhy(uint8_t allPhys, uint8_t txPhys, uint8_t rxPhys); +/*************************************************************************************************/ +/*! + * \brief Validate if specified PHYs are supported by LL. + * + * \param txPhys Preferred transmitter PHYs. + * \param rxPhys Preferred receiver PHYs. + * + * \return TRUE if all specified PHYs are supported. + */ +/*************************************************************************************************/ +bool_t llValidatePhySupport(uint8_t txPhys, uint8_t rxPhys); + /*************************************************************************************************/ /*! * \brief Set PHY for a connection. @@ -3017,12 +3257,12 @@ uint8_t LlGetPeerMinUsedChan(uint16_t handle, uint8_t *pPeerMinUsedChan); /*! * \brief Used to read the sleep clock accuracy of the peer device. * - * \param aclHandle Handle of the ACL. + * \param handle Handle of the ACL. * * \return Status error code. */ /*************************************************************************************************/ -uint8_t LlRequestPeerSca(uint16_t aclHandle); +uint8_t LlRequestPeerSca(uint16_t handle); /*! \} */ /* LL_API_CONN */ @@ -3064,8 +3304,6 @@ uint8_t LlExtCreateConn(const LlExtInitParam_t *pInitParam, const LlExtInitScanP /*! * \brief Cancel a create connection operation. * - * \return None. - * * Cancel a connection before it is established. This function is only used when operating * in master role. */ @@ -3253,14 +3491,24 @@ uint8_t LlGetIsoTxBufs(void); /*************************************************************************************************/ uint8_t LlGetIsoRxBufs(void); +/*************************************************************************************************/ +/*! + * \brief Read ISO link Quality stats. + * + * \param handle connection handle. + * \param pStats link quality statistics. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlReadIsoLinkQual(uint16_t handle, LlIsoLinkQual_t * pStats); + /*************************************************************************************************/ /*! * \brief Send an ACL data packet. * * \param pData Data buffer * - * \return None. - * * Send an ACL data packet. pData points to an ACL buffer formatted according to [1]; the host * must set the connection handle, flags, and length fields in the buffer. */ @@ -3273,12 +3521,10 @@ void LlSendAclData(uint8_t *pData); * * \return Data buffer. * - * Receive an ACL data packet. This function returns a pointer to an ACL buffer formatted - * according to [1]. The host must parse the header to determine the connection handle, flags, - * and length fields. If no ACL buffers are available this function returns NULL. + * Receive an ACL data packet. If no ACL buffers are available this function returns NULL. * - * The host must deallocate the buffer by calling WsfMsgFree() and call LlRecvBufCmpl() to - * update LL accounting. + * \note The host must deallocate the buffer by calling WsfMsgFree() and call LlRecvBufCmpl() to + * update LL accounting. */ /*************************************************************************************************/ uint8_t *LlRecvAclData(void); @@ -3289,8 +3535,6 @@ uint8_t *LlRecvAclData(void); * * \param numBufs Number of completed packets. * - * \return None. - * * Indicate that received ACL data buffer has been deallocated. */ /*************************************************************************************************/ @@ -3403,6 +3647,133 @@ uint8_t LlSetTxTestErrorPattern(uint32_t pattern); /*************************************************************************************************/ uint8_t LlModifySleepClockAccuracy(uint8_t action); +/*************************************************************************************************/ +/*! + * \brief Enable ISO Tx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoTxTest(uint16_t handle, uint8_t pldType); + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoRxTest(uint16_t handle, uint8_t pldType); + +/*************************************************************************************************/ +/*! + * \brief ISO read test counters. + * + * \param handle CIS or BIS handle. + * \param pCtr Test Counter. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoReadTestCounter(uint16_t handle, LlIsoTestCtrs_t *pCtr); + +/*************************************************************************************************/ +/*! + * \brief Terminate ISO Tx or Rx test. + * + * \param handle CIS or BIS handle. + * \param pCtr Test counters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoTestEnd(uint16_t handle, LlIsoTestCtrs_t *pCtr); + +/*************************************************************************************************/ +/*! + * \brief Set transmit power change reporting enable. + * + * \param handle Connection handle. + * \param enableLocal Enable local reporting. + * \param enableRemote Enable remote reporting. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetTxPowerReporting(uint16_t handle, uint8_t enableLocal, uint8_t enableRemote); + +/*************************************************************************************************/ +/*! + * \brief Set enable state for power monitoring. + * + * \param handle Handle identifier for connection. + * \param enable Enable status for power monitor. + * + * \return Status error code. + * + * \note Path loss must be disabled. + */ +/*************************************************************************************************/ +uint8_t LlSetPowerMonitorEnable(uint16_t handle, bool_t enable); + +/*************************************************************************************************/ +/*! + * \brief Set path loss monitoring parameters. + * + * \param handle Handle identifier for connection. + * \param highThresh High extreme threshold. + * \param highHyst High extreme hysteresis. + * \param lowThresh Low extreme threshold. + * \param lowHyst Low extreme hysteresis. + * \param minTime Minimum time spent to trigger event generation. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetPathLossReportingParams(uint16_t handle, uint8_t highThresh, uint8_t highHyst, uint8_t lowThresh, uint8_t lowHyst, uint16_t minTime); + +/*************************************************************************************************/ +/*! + * \brief Set path loss enable. + * + * \param handle Connection handle. + * \param enable Enable flag. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetPathLossReportingEnable(uint16_t handle, uint8_t enable); + +/*************************************************************************************************/ +/*! + * \brief Request change to or read peer txPower + * + * \param handle Connection handle. + * \param delta Requested change. + * \param phy Phy this change requests the change on. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlPowerCtrlReq(uint16_t handle, int8_t delta, uint8_t phy); + +/*************************************************************************************************/ +/*! + * \brief ISO event complete enable. + * + * \param enable Set to TRUE to enable, FALSE to disable. + * + * Enable or disable reports about the scanners from which an advertiser receives scan requests. + */ +/*************************************************************************************************/ +void LlIsoEventCompleteEnable(uint8_t enable); + /*! \} */ /* LL_API_TEST */ /*! \addtogroup LL_API_DIAG @@ -3503,7 +3874,6 @@ uint16_t LlStatsGetHandlerWatermarkUsec(void); /*! \} */ /* LL_API_DIAG */ - /*! \addtogroup LL_API_CIS * \{ */ @@ -3512,13 +3882,13 @@ uint16_t LlStatsGetHandlerWatermarkUsec(void); * \brief Used by a master host to set the parameters of all connected isochronous streams * associated with a connected isochronous group in the controller. * - * \param pSetCigParam CIG parameters. - * \param pCisHandles Return buffer for the connected isochronous stream handles. + * \param pCigParam CIG parameters. + * \param pCisHandles Return buffer for the connected isochronous handles. * * \return Status error code. */ /*************************************************************************************************/ -uint8_t LlSetCigParams(LlCisCigParams_t *pSetCigParam, uint16_t *pCisHandles); +uint8_t LlSetCigParams(LlCisCigParams_t *pCigParam, uint16_t *pCisHandles); /*************************************************************************************************/ /*! @@ -3526,7 +3896,7 @@ uint8_t LlSetCigParams(LlCisCigParams_t *pSetCigParam, uint16_t *pCisHandles); * associated with a connected isochronous group in the controller for testing purpose. * * \param pSetCigParamTest CIG test parameters. - * \param pCisHandles Return buffer for the connected isochronous stream handles. + * \param pCisHandles Return buffer for the connected isochronous handles. * * \return Status error code. */ @@ -3581,36 +3951,108 @@ uint8_t LlAcceptCisReq(uint16_t cisHandle); /*************************************************************************************************/ uint8_t LlRejectCisReq(uint16_t cisHandle, uint8_t reason); +/*************************************************************************************************/ +/*! + * \brief Used by a broadcaster host to command is used to create one or more BISes of a BIG + * in the controller. + * + * \param pCreateBig Create BIG parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlCreateBig(LlCreateBig_t *pCreateBig); + +/*************************************************************************************************/ +/*! + * \brief Used by a broadcaster host to command is used to create one or more BISes of a BIG + * in the ISO test mode. + * + * \param pCreateBigTest Create BIG Test parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlCreateBigTest(LlCreateBigTest_t *pCreateBigTest); + +/*************************************************************************************************/ +/*! + * \brief Used to terminate the transmission of all BISes of a BIG, or to cancel the process + * of creating a BIG using the HCI_LE_Create_BIG command from the Isochronous Broadcaster. + * + * \param bigHandle Used to identify the BIG. + * \param reason Termination reason. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlTerminateBig(uint8_t bigHandle, uint8_t reason); + +/*************************************************************************************************/ +/*! + * \brief Used to synchronize and receive PDUs from one or more BISes within a BIG. + * + * \param pCreateSync BIG Create Sync parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlBigCreateSync(LlBigCreateSync_t *pCreateSync); + +/*************************************************************************************************/ +/*! + * \brief Used to stop synchronization with the BIG or to cancel the process of synchronizing + * to BISes invoked by the HCI_LE_BIG_Create_Sync command + * + * \param bigHandle Used to identify the BIG. + */ +/*************************************************************************************************/ +void LlBigTerminateSync(uint8_t bigHandle); + +/*************************************************************************************************/ +/*! + * \brief Read the Time_Stamp and Time_Offset of a transmitted ISO_SDU identified by the + * Packet_Sequence_Number on a CIS or BIS identified by the Connection_Handle. + * + * \param handle BIS or CIS handle. + * \param pPktSn Packet sequence number. + * \param pTs Timestamp. + * \param pTimeOffs Time offset. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlReadIsoTxSync(uint16_t handle, uint16_t *pPktSn, uint32_t *pTs, uint32_t *pTimeOffs); + /*************************************************************************************************/ /*! * \brief Used to identify and enable the isochronous data path between the host and the - * controller for each connected isochronous stream or broadcast isochronous stream. + * controller for each connected isochronous or broadcast isochronous stream. * - * \param pSetupDataPathParam Parameters for setup ISO data path. + * \param pSetupDataPath Parameters for setup ISO data path. * * \return Status error code. */ /*************************************************************************************************/ -uint8_t LlSetupIsoDataPath(LlIsoSetupDataPathParams_t *pSetupDataPathParam); +uint8_t LlSetupIsoDataPath(LlIsoSetupDataPath_t *pSetupDataPath); /*************************************************************************************************/ /*! * \brief Used to remove the isochronous data path associated with the - * connected isochronous stream or broadcast isochronous stream. + * connected isochronous or broadcast isochronous stream. * - * \param isoHandle Handle for CIS or BIS. + * \param handle Handle for CIS or BIS. + * \param dpDir Direction of data path to remove. * * \return Status error code. */ /*************************************************************************************************/ -uint8_t LlRemoveIsoDataPath(uint16_t isoHandle); +uint8_t LlRemoveIsoDataPath(uint16_t handle, uint8_t dpDir); /*************************************************************************************************/ /*! * \brief Initialize LL subsystem for operation for slave connected isochronous stream. * - * \return None. - * * This function initializes the LL subsystem for use as a slave connected isochronous stream. */ /*************************************************************************************************/ @@ -3620,8 +4062,6 @@ void LlCisSlaveInit(void); /*! * \brief Initialize LL subsystem for operation for master connected isochronous stream. * - * \return None. - * * This function initializes the LL subsystem for use as a master connected isochronous stream. */ /*************************************************************************************************/ @@ -3646,105 +4086,101 @@ uint16_t LlInitCisMem(uint8_t *pFreeMem, uint32_t freeMemSize); /*************************************************************************************************/ /*! - * \brief Initialize memory for ISO. + * \brief Initialize LL subsystem for operation for slave broadcast isochronous stream. * - * \param pFreeMem Pointer to free memory. - * \param freeMemSize Size of pFreeMem. - * - * \return Amount of free memory consumed. - * - * This function allocates memory for CIS. - * - * \note This routine must be called after LlInitRunTimeCfg() but only once before any - * other initialization routines. + * This function initializes the LL subsystem for use as a slave broadcast isochronous stream. */ /*************************************************************************************************/ -uint16_t LlInitIsoMem(uint8_t *pFreeMem, uint32_t freeMemSize); +void LlBisSlaveInit(void); /*************************************************************************************************/ /*! - * \brief Send an ISO data packet. + * \brief Initialize LL subsystem for operation for master broadcast isochronous stream. * - * \param pData Data buffer - * - * \return None. - * - * Send an ISO data packet. pData points to an ISO buffer formatted according to [1]; the host - * must set the connection handle, flags, and length fields in the buffer. + * This function initializes the LL subsystem for use as a master broadcast isochronous stream. */ /*************************************************************************************************/ -void LlSendIsoData(uint8_t *pData); +void LlBisMasterInit(void); /*************************************************************************************************/ /*! - * \brief Receive an ISO data packet + * \brief Initialize memory for BIS. * - * \return Data buffer. + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. * - * Receive an ISO data packet. This function returns a pointer to an ISO buffer formatted - * according to [1]. The host must parse the header to determine the connection handle, flags, - * and length fields. If no ISO buffers are available this function returns NULL. + * \return Amount of free memory consumed. * - * The host must deallocate the buffer by calling WsfMsgFree() and call LlRecvBufCmpl() to - * update LL accounting. + * This function allocates memory for BIS. + * + * \note This routine must be called after LlInitRunTimeCfg() but only once before any + * other initialization routines. */ /*************************************************************************************************/ -uint8_t *LlRecvIsoData(void); +uint16_t LlInitBisMem(uint8_t *pFreeMem, uint32_t freeMemSize); /*************************************************************************************************/ /*! - * \brief Indicate that received ISO data buffer has been deallocated + * \brief Initialize memory for ISO. * - * \param numBufs Number of completed packets. + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. * - * \return None. + * This function allocates memory for CIS. * - * Indicate that received ISO data buffer has been deallocated. + * \note This routine must be called after LlInitRunTimeCfg() but only once before any + * other initialization routines. */ /*************************************************************************************************/ -void LlRecvIsoDataComplete(uint8_t numBufs); +uint16_t LlInitIsoMem(uint8_t *pFreeMem, uint32_t freeMemSize); /*************************************************************************************************/ /*! - * \brief Enable ISO Tx test. + * \brief Initialize LL for use with an audio codec. * - * \param isoHandle CIS or BIS handle. - * \param plLen Payload length type. + * Assign codec functions for direct LL audio streaming. + */ +/*************************************************************************************************/ +void LlInitCodec(void); + +/*************************************************************************************************/ +/*! + * \brief Send an ISO data packet. * - * \return Status error code. + * \param pData Data buffer * + * Send an ISO data packet. pData points to an ISO buffer formatted according to [1]; the host + * must set the connection handle, flags, and length fields in the buffer. */ /*************************************************************************************************/ -uint8_t LlIsoTxTest(uint16_t isoHandle, uint8_t plLen); +void LlSendIsoData(uint8_t *pData); /*************************************************************************************************/ /*! - * \brief Enable ISO Rx test. + * \brief Receive an ISO data packet * - * \param isoHandle CIS or BIS handle. - * \param plLen Payload length type. + * \return Data buffer. * - * \return Status error code. + * Receive an ISO data packet. If no ISO buffers are available this function returns NULL. * + * \note The host must deallocate the buffer by calling WsfMsgFree() and call LlRecvBufCmpl() to + * update LL accounting. */ /*************************************************************************************************/ -uint8_t LlIsoRxTest(uint16_t isoHandle, uint8_t plLen); +uint8_t *LlRecvIsoData(void); /*************************************************************************************************/ /*! - * \brief ISO read test counter. - * - * \param isoHandle CIS or BIS handle. - * \param pRcvedPlCounter Pointer to the received payload counter as return parameter. - * \param pMissedPlCounter Pointer to the missed payload counter as return parameter. - * \param pFailedPlCounter Pointer to the failed payload counter as return parameter. - * \param termTest TRUE if terminate the test, FALSE otherwise. + * \brief Indicate that received ISO data buffer has been deallocated * - * \return Status error code. + * \param numBufs Number of completed packets. * + * Indicate that received ISO data buffer has been deallocated. */ /*************************************************************************************************/ -uint8_t LlIsoReadTestCounter(uint16_t isoHandle, uint32_t *pRcvedPlCounter, uint32_t *pMissedPlCounter, uint32_t *pFailedPlCounter, bool_t termTest); +void LlRecvIsoDataComplete(uint8_t numBufs); /*! \} */ /* LL_API_CIS */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_defs.h deleted file mode 100644 index 3e50ac51722..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_defs.h +++ /dev/null @@ -1,492 +0,0 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer constant definitions. - */ -/*************************************************************************************************/ - -#ifndef LL_DEFS_H -#define LL_DEFS_H - -#include "wsf_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************************************** - Constants -**************************************************************************************************/ - -/*** Version ***/ - -#define LL_VER_BT_CORE_SPEC_4_0 0x06 /*!< Bluetooth core specification 4.0 */ -#define LL_VER_BT_CORE_SPEC_4_1 0x07 /*!< Bluetooth core specification 4.1 */ -#define LL_VER_BT_CORE_SPEC_4_2 0x08 /*!< Bluetooth core specification 4.2 */ -#define LL_VER_BT_CORE_SPEC_5_0 0x09 /*!< Bluetooth core specification 5.0 */ -#define LL_VER_BT_CORE_SPEC_5_1 0x0A /*!< Bluetooth core specification 5.1 */ -#define LL_VER_BT_CORE_SPEC_MILAN 0x0B /*!< Bluetooth core specification Milan */ -#define LL_VER_BT_CORE_SPEC_SYDNEY 0x0C /*!< Bluetooth core specification Sydney */ - -#define LL_COMP_ID_ARM 0x005F /*!< ARM Ltd. company ID. */ - -/*** Common ***/ - -#define LL_RSSI_MIN -127 /*!< Minimum RSSI value. */ -#define LL_RSSI_MAX 20 /*!< Maximum RSSI value. */ -#define LL_RSSI_NOT_AVAIL 127 /*!< RSSI is not available. */ - -#define LL_CRC_LEN 3 /*!< CRC length. */ -#define LL_AA_LEN 4 /*!< Access address length. */ -#define LL_PREAMBLE_LEN_1M 1 /*!< Preamble length (LE 1M PHY). */ -#define LL_PREAMBLE_LEN_2M 2 /*!< Preamble length (LE 2M PHY). */ -#define LL_PREAMBLE_LEN_CODED_BITS 10 /*!< Preamble length (LE Coded PHY). */ -#define LL_CI_LEN_BITS 2 /*!< Coding indicator length (LE Coded PHY). */ -#define LL_TERM1_LEN_BITS 3 /*!< TERM1 length (LE Coded PHY). */ -#define LL_TERM2_LEN_BITS 3 /*!< TERM2 length (LE Coded PHY). */ - -#define LL_RAND_ADDR_TYPE_MASK UINT64_C(0xC00000000000) /*!< BD Random Address type mask. */ -#define LL_RAND_ADDR_TYPE_STATIC UINT64_C(0xC00000000000) /*!< Static Random Address type. */ -#define LL_RAND_ADDR_TYPE_RPA UINT64_C(0x400000000000) /*!< Resolvable Private Address type. */ -#define LL_RAND_ADDR_TYPE_NRPA UINT64_C(0x000000000000) /*!< Non-Resolvable Private Address type. */ - -/*** Advertising PDU ***/ - -/*! \brief Advertising channel PDU types. */ -enum -{ - /* --- Core Spec 4.0 --- */ - LL_PDU_ADV_IND = 0, /*!< Connectable undirected advertising PDU. */ - LL_PDU_ADV_DIRECT_IND = 1, /*!< Connectable directed advertising PDU. */ - LL_PDU_ADV_NONCONN_IND = 2, /*!< Non-connectable undirected advertising PDU. */ - LL_PDU_SCAN_REQ = 3, /*!< Scan request PDU. */ - LL_PDU_SCAN_RSP = 4, /*!< Scan response PDU. */ - LL_PDU_CONNECT_IND = 5, /*!< Connect indication PDU. */ - LL_PDU_ADV_SCAN_IND = 6, /*!< Scannable undirected advertising PDU. */ - /* --- Core Spec 5.0 --- */ - LL_PDU_AUX_SCAN_REQ = 3, /*!< Auxiliary scan request PDU. */ - LL_PDU_AUX_CONNECT_REQ = 5, /*!< Auxiliary connect request PDU. */ - LL_PDU_ADV_EXT_IND = 7, /*!< Extended advertising PDU. */ - LL_PDU_AUX_ADV_IND = 7, /*!< Auxiliary advertising PDU. */ - LL_PDU_AUX_SCAN_RSP = 7, /*!< Auxiliary scan response PDU. */ - LL_PDU_AUX_SYNC_IND = 7, /*!< Auxiliary synchronize PDU. */ - LL_PDU_AUX_CHAIN_IND = 7, /*!< Auxiliary chain PDU. */ - LL_PDU_AUX_CONNECT_RSP = 8, /*!< Auxiliary connect response PDU. */ -}; - -#define LL_SCAN_REQ_PDU_LEN 12 /*!< Size of a scan request PDU. */ -#define LL_CONN_IND_PDU_LEN 34 /*!< Size of a connect indication PDU. */ -#define LL_CONN_RSP_PDU_LEN 14 /*!< Size of an auxiliary connect response PDU. */ - -#define LL_CHAN_ADV_MIN_IDX 37 /*!< Minimum advertising channel index. */ -#define LL_CHAN_ADV_MAX_IDX 39 /*!< Maximum advertising channel index. */ -#define LL_NUM_CHAN_ADV 3 /*!< Total number of advertising channels. */ - -#define LL_ADVBU_MAX_LEN 31 /*!< Maximum advertising channel host data length. */ -#define LL_ADVB_MAX_LEN 39 /*!< Maximum advertising channel PDU length. */ -#define LL_ADVB_MIN_LEN (LL_ADVB_MAX_LEN - LL_ADVBU_MAX_LEN) /*!< Minimum advertising channel packet length. */ -#define LL_ADVB_MAX_TIME_1M ((LL_BLE_US_PER_BYTE_1M * (LL_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_1M) - /*!< Maximum time for a 1M advertising channel PDU. */ -#define LL_ADVB_MAX_TIME_2M ((LL_BLE_US_PER_BYTE_2M * (LL_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_2M) - /*!< Maximum time for a 2M advertising channel PDU. */ -#define LL_ADVB_MAX_TIME_S2 ((LL_BLE_US_PER_BYTE_CODED_S2 * (LL_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S2) - /*!< Maximum time for a Coded S2 advertising channel PDU. */ -#define LL_ADVB_MAX_TIME_S8 ((LL_BLE_US_PER_BYTE_CODED_S8 * (LL_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8) - /*!< Maximum time for a Coded S8 advertising channel PDU. */ - -#define LL_ADV_PKT_MAX_USEC LL_ADVB_MAX_TIME_1M /*!< Maximum time in microseconds for an advertising packet. */ -#define LL_SCAN_REQ_MAX_USEC ((8 * (LL_ADV_PREFIX_LEN + LL_SCAN_PREFIX_LEN)) + LL_MIN_PKT_TIME_US_1M) - /*!< Maximum time in microseconds for a scan request packet. */ -#define LL_SCAN_RSP_MAX_USEC LL_ADVB_MAX_TIME_1M /*!< Maximum time in microseconds for a scan response packet. */ - -#define LL_ADV_HDR_LEN 2 /*!< Advertising channel header length. */ -#define LL_ADV_HDR_TYPE_OFFS 0 /*!< Advertising header type offset. */ -#define LL_ADV_HDR_TYPE_MSK 0x0F /*!< Advertising header type mask. */ -#define LL_ADV_HDR_LEN_OFFS 1 /*!< Advertising header length offset. */ -#define LL_ADV_HDR_LEN_MSK 0x3F /*!< Advertising header length mask for 4.2. */ -#define LL_ADV_EXT_HDR_LEN_MSK 0xFF /*!< Advertising extension header length mask for 5.0. */ -#define LL_ADV_PREFIX_LEN 6 /*!< Advertising PDU payload prefix length (AdvA). */ -#define LL_SCAN_PREFIX_LEN 6 /*!< Scan request/response PDU payload prefix length (AdvA). */ - -#define LL_ADV_ACCESS_ADDR UINT32_C(0x8E89BED6) /*!< Advertising channel access address. */ -#define LL_ADV_CRC_INIT UINT32_C(0x555555) /*!< Advertising CRC initial value. */ - -#define LL_DIR_ADV_INTER_TICKS 6 /*!< Advertising interval between directed advertising events (3.75 ms). */ -#define LL_DIR_ADV_DUR_TICKS 2048 /*!< Maximum high duty cycle directed advertising duration (1.28 seconds). */ - -/*! \brief Extended header bit definition. */ -enum -{ - LL_EXT_HDR_ADV_ADDR_BIT = (1 << 0), /*!< Extended header AdvA bit. */ - LL_EXT_HDR_TGT_ADDR_BIT = (1 << 1), /*!< Extended header TargetA bit. */ - LL_EXT_HDR_CTE_INFO_BIT = (1 << 2), /*!< Extended header CTEInfo bit. */ - LL_EXT_HDR_ADI_BIT = (1 << 3), /*!< Extended header AdvDataInfo bit. */ - LL_EXT_HDR_AUX_PTR_BIT = (1 << 4), /*!< Extended header AuxPtr bit. */ - LL_EXT_HDR_SYNC_INFO_BIT = (1 << 5), /*!< Extended header SyncInfo bit. */ - LL_EXT_HDR_TX_PWR_BIT = (1 << 6), /*!< Extended header TxPower bit. */ -}; - -#define LL_MAX_ADV_HANDLE 0xEF /*!< Maximum advertising handle. */ -#define LL_MAX_ADV_SID 0x0F /*!< Maximum advertising SID */ - -#define LL_EXT_ADV_HDR_MIN_LEN 1 /*!< Minimum extended advertising header length (ExtHdrLen and AdvMode fields). */ -#define LL_EXT_ADV_HDR_MAX_LEN 64 /*!< Maximum extended advertising header length (ExtHdrLen, AdvMode fields and Extended header). */ -#define LL_EXT_HDR_FLAG_LEN 1 /*!< Length of extended header flag field */ -#define LL_EXT_ADVBU_MAX_LEN 251 /*!< Maximum extended advertising channel PDU host data length. */ -#define LL_EXT_ADVB_MAX_LEN 257 /*!< Maximum extended advertising channel PDU length. */ -#define LL_EXT_ADVB_NORMAL_LEN 50 /*!< Normal extended advertising channel PDU length. */ - -#define LL_EXT_HDR_ACAD_MAX_LEN LL_EXT_ADV_HDR_MAX_LEN - LL_EXT_ADV_HDR_MIN_LEN - LL_EXT_HDR_FLAG_LEN /*!< Maximum possible ACAD length (Max extended header minus ExtHdrLen, AdvMode, and extended header flag field. */ - -#define LL_EXT_ADVB_MAX_TIME_1M ((LL_BLE_US_PER_BYTE_1M * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_1M) - /*!< Maximum time for a 1M advertising channel PDU. */ -#define LL_EXT_ADVB_MAX_TIME_2M ((LL_BLE_US_PER_BYTE_2M * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_2M) - /*!< Maximum time for a 2M advertising channel PDU. */ -#define LL_EXT_ADVB_MAX_TIME_S2 ((LL_BLE_US_PER_BYTE_CODED_S2 * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S2) - /*!< Maximum time for a Coded S2 advertising channel PDU. */ -#define LL_EXT_ADVB_MAX_TIME_S8 ((LL_BLE_US_PER_BYTE_CODED_S8 * (LL_EXT_ADVB_MAX_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8) - /*!< Maximum time for a Coded S8 advertising channel PDU. */ -#define LL_EXT_ADVB_NORMAL_TIME_S8 ((LL_BLE_US_PER_BYTE_CODED_S8 * (LL_EXT_ADVB_NORMAL_LEN - LL_ADV_HDR_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8) - /*!< Time for a Coded S8 advertising channel PDU with normal length. */ - -#define LL_AUX_PTR_MAX_USEC 2457600 /*!< Maximum AuxPtr offset value in microseconds. */ - -#define LL_SYNC_MIN_TIMEOUT 0x000A /*!< Minimum synchronization timeout. */ -#define LL_SYNC_MAX_TIMEOUT 0x4000 /*!< Maximum synchronization timeout. */ -#define LL_SYNC_MAX_SKIP 0x01F3 /*!< Maximum synchronization skip. */ -#define LL_SYNC_MAX_HANDLE 0x0EFF /*!< Maximum synchronization handle. */ - -#define LL_PER_ADV_INT_MIN 0x0006 /*!< Minimum periodic advertising interval. */ - -#define LL_SYNC_OFFS_ADJUST_USEC LL_AUX_PTR_MAX_USEC /*!< Sync offset adjust of 2.4576 seconds. */ -#define LL_SYNC_INFO_LEN 18 /*!< Size of SyncInfo field. */ - -/*! \brief Periodic sync transfer receive mode. */ -enum -{ - LL_SYNC_TRSF_MODE_OFF = 0, /*!< Periodic sync transfer receive is disabled. */ - LL_SYNC_TRSF_MODE_REP_DISABLED = 1, /*!< Periodic sync transfer receive is enabled, report event is disabled. */ - LL_SYNC_TRSF_MODE_REP_ENABLED = 2, /*!< Periodic sync transfer receive is enabled, report event is enabled. */ - LL_SYNC_TRSF_MAX_MODE = LL_SYNC_TRSF_MODE_REP_ENABLED -}; - -/*** Data PDU ***/ - -/*! \brief Data channel LL Control PDU types. */ -enum -{ - /* --- Core Spec 4.0 --- */ - LL_PDU_CONN_UPDATE_IND = 0x00, /*!< Connection update indication PDU. */ - LL_PDU_CHANNEL_MAP_IND = 0x01, /*!< Channel map indication PDU. */ - LL_PDU_TERMINATE_IND = 0x02, /*!< Terminate indication PDU. */ - LL_PDU_ENC_REQ = 0x03, /*!< Encryption request PDU. */ - LL_PDU_ENC_RSP = 0x04, /*!< Encryption response PDU. */ - LL_PDU_START_ENC_REQ = 0x05, /*!< Start encryption request PDU. */ - LL_PDU_START_ENC_RSP = 0x06, /*!< Start encryption response PDU. */ - LL_PDU_UNKNOWN_RSP = 0x07, /*!< Unknown response PDU. */ - LL_PDU_FEATURE_REQ = 0x08, /*!< Feature request PDU. */ - LL_PDU_FEATURE_RSP = 0x09, /*!< Feature response PDU. */ - LL_PDU_PAUSE_ENC_REQ = 0x0A, /*!< Pause encryption request PDU. */ - LL_PDU_PAUSE_ENC_RSP = 0x0B, /*!< Pause encryption response PDU. */ - LL_PDU_VERSION_IND = 0x0C, /*!< Version indication PDU. */ - LL_PDU_REJECT_IND = 0x0D, /*!< Reject indication PDU. */ - /* --- Core Spec 4.2 --- */ - LL_PDU_SLV_FEATURE_REQ = 0x0E, /*!< Slave feature request PDU. */ - LL_PDU_CONN_PARAM_REQ = 0x0F, /*!< Connection parameter request PDU. */ - LL_PDU_CONN_PARAM_RSP = 0x10, /*!< Connection parameter response PDU. */ - LL_PDU_REJECT_EXT_IND = 0x11, /*!< Reject extended indication PDU. */ - LL_PDU_PING_REQ = 0x12, /*!< Ping request PDU. */ - LL_PDU_PING_RSP = 0x13, /*!< Ping response PDU. */ - LL_PDU_LENGTH_REQ = 0x14, /*!< Data length request PDU. */ - LL_PDU_LENGTH_RSP = 0x15, /*!< Data length response PDU. */ - /* --- Core Spec 5.0 --- */ - LL_PDU_PHY_REQ = 0x16, /*!< PHY request PDU. */ - LL_PDU_PHY_RSP = 0x17, /*!< PHY response PDU. */ - LL_PDU_PHY_UPDATE_IND = 0x18, /*!< PHY update indication PDU. */ - LL_PDU_MIN_USED_CHAN_IND = 0x19, /*!< Minimum used channels indication PDU. */ - /* --- Core Spec 5.1 --- */ - // 0x1A 0x1B for AOA AOD, 0x1C for PAST 0x20 RFU - LL_PDU_PERIODIC_SYNC_IND = 0x1C, /*!< Periodic sync indication PDU. */ - /* --- Core Spec Milan --- */ - LL_PDU_PEER_SCA_REQ = 0x1D, /*!< Peer SCA request PDU. */ - LL_PDU_PEER_SCA_RSP = 0x1E, /*!< Peer SCA response PDU. */ - LL_PDU_CIS_REQ = 0x1F, /*!< CIS request PDU. */ - LL_PDU_CIS_RSP = 0x21, /*!< CIS response PDU. */ - LL_PDU_CIS_IND = 0x22, /*!< CIS indication PDU. */ - LL_PDU_CIS_TERM_IND = 0x23, /*!< CIS terminate indication PDU. */ - - LL_PDU_UNSPECIFIED = 0xFF /*!< Unspecified PDU. */ -}; - -/* Data PDU length */ -/* --- Core Spec 4.0 --- */ -#define LL_CONN_UPD_IND_PDU_LEN 12 /*!< Connection update indication PDU length. */ -#define LL_CHAN_MAP_IND_PDU_LEN 8 /*!< Channel map indication PDU length. */ -#define LL_TERMINATE_IND_PDU_LEN 2 /*!< Terminate indication PDU length. */ -#define LL_ENC_REQ_LEN 23 /*!< Encryption request PDU length. */ -#define LL_ENC_RSP_LEN 13 /*!< Encryption response PDU length. */ -#define LL_START_ENC_LEN 1 /*!< Start encryption request/response PDU length. */ -#define LL_UNKNOWN_RSP_LEN 2 /*!< Unknown response PDU length. */ -#define LL_FEATURE_PDU_LEN 9 /*!< Feature request/response PDU length. */ -#define LL_PAUSE_ENC_LEN 1 /*!< Pause encryption request/response PDU length. */ -#define LL_VERSION_IND_PDU_LEN 6 /*!< Version indication PDU length. */ -#define LL_REJECT_IND_PDU_LEN 2 /*!< Reject indication PDU length. */ -/* --- Core Spec 4.2 --- */ -#define LL_CONN_PARAM_PDU_LEN 24 /*!< Connection parameter request or response PDU length. */ -#define LL_REJECT_EXT_IND_PDU_LEN 3 /*!< Reject extended indication PDU length. */ -#define LL_PING_PDU_LEN 1 /*!< Ping request/response PDU length. */ -#define LL_DATA_LEN_PDU_LEN 9 /*!< Data length request or response PDU length. */ -/* --- Core Spec 5.0 --- */ -#define LL_PHY_PDU_LEN 3 /*!< PHY request/response PDU length. */ -#define LL_PHY_UPD_IND_PDU_LEN 5 /*!< PHY update indication PDU length. */ -#define LL_MIN_USED_CHAN_PDU_LEN 3 /*!< Minimum used channels indication PDU length. */ -/* --- Core Spec 5.1 --- */ -#define LL_PERIODIC_SYNC_PDU_LEN 35 /*!< Periodic sync indication PDU length. */ -/* --- Core Spec Milan --- */ -#define LL_PEER_SCA_REQ_LEN 2 /*!< Peer SCA request PDU length. */ -#define LL_PEER_SCA_RSP_LEN 2 /*!< Peer SCA response PDU length. */ -#define LL_CIS_REQ_LEN 34 /*!< CIS request PDU length. */ -#define LL_CIS_RSP_LEN 9 /*!< CIS response PDU length. */ -#define LL_CIS_IND_LEN 16 /*!< CIS indication PDU length. */ -#define LL_CIS_TERM_LEN 4 /*!< CIS termination PDU length. */ -#define LL_CIS_SDU_CONFIG_REQ_LEN 13 /*!< CIS SDU config request PDU length. */ -#define LL_CIS_SDU_CONFIG_RSP_LEN 4 /*!< CIS SDU config response PDU length. */ - -#define LL_EMPTY_PDU_LEN 2 /*!< Length of an empty data PDU. */ - -#define LL_DATA_HDR_LEN 2 /*!< Data channel header length. */ -#define LL_DATA_MIC_LEN 4 /*!< Data channel PDU MIC length. */ - -#define LL_DATA_HDR_LLID_MSK 0x03 /*!< Data PDU LLID mask. */ -#define LL_DATA_HDR_LEN_MSK 0xFF /*!< Data header length mask. BLE 4.2 data len extension allows 8 bits. */ - -#define LL_MAX_NUM_CHAN_DATA 37 /*!< Maximum number of used data channels. */ -#define LL_MIN_NUM_CHAN_DATA 2 /*!< Minimum number of used data channels. */ - -#define LL_ISO_DATA_HDR_LEN 2 /*!< ISO data PDU header length. */ -#define LL_ISO_DATA_MIC_LEN 4 /*!< ISO data PDU MIC length. */ - -#define LL_ISO_DATA_HDR_LLID_MSK 0x03 /*!< ISO data PDU LLID mask. */ -#define LL_ISO_DATA_HDR_LEN_MSK 0xFF /*!< ISO Data header length mask. */ - -/*! \brief Data PDU LLID types. */ -enum -{ - LL_LLID_VS_PDU = 0x00, /*!< Vendor specific PDU. */ - /* N.B. next two enumerations intentionally use identical values. */ - LL_LLID_EMPTY_PDU = 0x01, /*!< Empty PDU. */ - LL_LLID_CONT_PDU = 0x01, /*!< Data PDU: continuation fragment of an L2CAP message. */ - LL_LLID_START_PDU = 0x02, /*!< Data PDU: start of an L2CAP message or a complete L2CAP message with no fragmentation. */ - LL_LLID_CTRL_PDU = 0x03, /*!< Control PDU. */ -}; - -/*** Encryption ***/ - -#define LL_ECC_KEY_LEN 32 /*!< ECC key length. */ - -#define LL_DEF_RES_ADDR_TO_SEC 900 /*!< Default resolvable address timeout in seconds. */ - -#define LL_RAND_LEN 8 /*!< Length of random number */ -#define LL_KEY_LEN 16 /*!< Encryption key length. */ -#define LL_SKD_LEN LL_KEY_LEN /*!< Session key diversifier length. */ -#define LL_IV_LEN 8 /*!< Initialization vector length. */ - -#define LL_DEF_AUTH_TO_MS 30000 /*!< Default authentication timeout in milliseconds. */ - -/*** LLCP ***/ - -#define LL_DATA_LEN_TO_TIME_1M(len) ((LL_BLE_US_PER_BYTE_1M * ((len) + LL_DATA_MIC_LEN)) + LL_MIN_PKT_TIME_US_1M) - /*!< Convert data length to time. */ -#define LL_DATA_LEN_TO_TIME_2M(len) ((LL_BLE_US_PER_BYTE_2M * ((len) + LL_DATA_MIC_LEN)) + LL_MIN_PKT_TIME_US_2M) - /*!< Convert data length to time. */ -#define LL_DATA_LEN_TO_TIME_CODED_S8(len) ((LL_BLE_US_PER_BYTE_CODED_S8 * ((len) + LL_DATA_MIC_LEN)) + LL_MIN_PKT_TIME_US_CODED_S8) - /*!< Convert data length to time. */ -#define LL_DATA_LEN_TO_TIME_CODED_S2(len) ((LL_BLE_US_PER_BYTE_CODED_S2 * ((len) + LL_DATA_MIC_LEN)) + LL_MIN_PKT_TIME_US_CODED_S2) - /*!< Convert data length to time. */ - -#define LL_MIN_INSTANT 6 /*!< Minimum number of CE to apply a CONN_UPD or CHAN_MAP. */ - -#define LL_MAX_ADV_DATA_LEN 1650 /*!< Maximum advertising data length. */ - -#define LL_MAX_DATA_LEN_MIN 27 /*!< Minimum value for maximum Data PDU length */ -#define LL_MAX_DATA_LEN_ABS_MAX 251 /*!< Absolute maximum limit for maximum Data PDU length */ - -#define LL_MAX_DATA_TIME_MIN 328 /*!< Minimum value for maximum Data PDU time */ -#define LL_MAX_DATA_TIME_ABS_MAX 17040 /*!< Absolute maximum limit for maximum Data PDU time */ -#define LL_MAX_DATA_TIME_ABS_MAX_1M 2120 /*!< Absolute maximum limit for maximum Data PDU time (LE 1M PHY) */ -#define LL_MAX_DATA_TIME_ABS_MIN_CODED 2704 /*!< Absolute minimum limit for maximum Data PDU time (CODED PHY) */ - -#define LL_T_PRT_SEC 40 /*!< LLCP procedure response timeout in seconds. */ - -#define LL_MAX_ADV_DLY_MS 10 /*!< Maximum advertising delay in milliseconds. */ - -#define LL_MIN_CONN_INTERVAL 6 /*!< Minimum value for connection interval. */ -#define LL_MAX_CONN_INTERVAL 3200 /*!< Maximum value for connection interval. */ - -#define LL_MIN_TX_WIN_SIZE 1 /*!< Minimum value for transmit window size. */ -#define LL_MAX_TX_WIN_SIZE 8 /*!< Maximum value for transmit window size. */ - -#define LL_MAX_CONN_LATENCY 499 /*!< Maximum value for connection slave latency. */ - -#define LL_MIN_SUP_TIMEOUT 10 /*!< Minimum value for connection supervision timeout. */ -#define LL_MAX_SUP_TIMEOUT 3200 /*!< Maximum value for connection supervision timeout. */ - -#define LL_MIN_POWER_THRESHOLD -128 /*!< Minimum value for power threshold. */ -#define LL_MAX_POWER_THRESHOLD 127 /*!< Maximum value for power threshold. */ - -#define LL_MAX_PHYS 3 /*!< Number of LE PHYs. */ -#define LL_ALL_PHYS_MSK 0x7 /*!< All supported LE PHYs mask. */ - -/*** ISO ***/ -#define LL_MAX_ISO_DATA_LEN_ABS_MAX 251 /*!< Absolute maximum limit for maximum ISO Data PDU length */ - -#define LL_MAX_CIS_COUNT 0x10 /*!< Maximum count for CIS. */ - -#define LL_MIN_CIG_ID 0x00 /*!< Minimum value for CIG ID. */ -#define LL_MAX_CIG_ID 0xEF /*!< Maximum value for CIG ID. */ - -#define LL_MIN_CIS_ID 0x00 /*!< Minimum value for CIS ID. */ -#define LL_MAX_CIS_ID 0xEF /*!< Maximum value for CIS ID. */ - -#define LL_MIN_ISO_INTERV 0x0004 /*!< Minimum value for ISO interval. */ -#define LL_MAX_ISO_INTERV 0x0C80 /*!< Maximum value for ISO interval. */ - -#define LL_MIN_ISOAL_PDU_TYPE 0x00 /*!< Minimum value for ISOAL PDU type. */ -#define LL_MAX_ISOAL_PDU_TYPE 0x01 /*!< Maximum value for ISOAL PDU type. */ - -#define LL_MIN_SDU_SIZE 0x000 /*!< Minimum value for SDU size. */ -#define LL_MAX_SDU_SIZE 0xFFF /*!< Maximum value for SDU size. */ - -#define LL_MIN_SDU_INTERV 0x000FF /*!< Minimum value for SDU interval. */ -#define LL_MAX_SDU_INTERV 0xFFFFF /*!< Maximum value for SDU interval. */ - -#define LL_MIN_CIS_NSE 0x00 /*!< Minimum value for CIS number of subevent. */ -#define LL_MAX_CIS_NSE 0x1F /*!< Maximum value for CIS number of subevent. */ - -#define LL_MIN_CIS_PL 0x00 /*!< Minimum value for CIS payload. */ -#define LL_MAX_CIS_PL 0xFB /*!< Maximum value for CIS payload. */ - -#define LL_MIN_CIS_PHY_BIT 0x00 /*!< Minimum value for CIS PHY bit. */ -#define LL_MAX_CIS_PHY_BIT 0x02 /*!< Maximum value for CIS PHY bit. */ - -#define LL_MIN_CIS_FT 0x01 /*!< Minimum value for CIS flush time. */ -#define LL_MAX_CIS_FT 0x1F /*!< Maximum value for CIS flush time. */ - -#define LL_MIN_CIS_BN 0x00 /*!< Minimum value for CIS burst number. */ -#define LL_MAX_CIS_BN 0x10 /*!< Maximum value for CIS burst number. */ - -/*! \brief ISO PDU LLID types. */ -enum -{ - LL_ISO_LLID_CIS_DATA_PDU = 0x00, /*!< CIS data PDU. */ - LL_ISO_LLID_BIS_DATA_PDU = 0x00, /*!< BIS data PDU. */ - LL_ISO_LLID_BIS_CTRL_PDU = 0x03, /*!< BIS control PDU. */ -}; - -/*! \brief ISO PDU types. */ -enum -{ - LL_ISO_PDU_TYPE_UNFRAMED = 0x00, /*!< Unframed PDU type. */ - LL_ISO_PDU_TYPE_FRAMED = 0x01, /*!< framed PDU type. */ -}; - -/*! \brief ISO PDU types. */ -enum -{ - LL_ISO_TEST_PL_LEN_MAX = 0x00, /*!< \brief Maximum length test payload */ - LL_ISO_TEST_PL_LEN_VAR = 0x01, /*!< \brief Maximum length test payload */ - LL_ISO_TEST_PL_LEN_ZERO = 0x02, /*!< \brief Maximum length test payload */ -}; - -/*** DTM ***/ - -#define LL_DTM_HDR_LEN 2 /*!< Direct Test Mode PDU header length. */ -#define LL_DTM_SYNC_WORD UINT32_C(0x71764129) /*!< Direct Test Mode sync word. */ -#define LL_DTM_CRC_INIT UINT32_C(0x555555) /*!< Direct Test Mode CRC initial value. */ -#define LL_DTM_MAX_INT_US 12500 /*!< Maximum time interval between packets in microseconds. */ -#define LL_DTM_PDU_ABS_MAX_LEN 255 /*!< Absolute maximum DTM PDU length. */ -#define LL_DTM_MAX_CHAN_IDX 39 /*!< Maximum channel index. */ - -/*** Baseband ***/ - -#define LL_CHAN_DATA_MIN_IDX 0 /*!< Minimum data channel index. */ -#define LL_CHAN_DATA_MAX_IDX 36 /*!< Maximum data channel index. */ -#define LL_CHAN_DATA_ALL UINT64_C(0x0000001FFFFFFFFF) /*!< Maximum data channel index. */ - -#define LL_BLE_BIT_PER_US 1 /*!< BLE PHY rate. */ -#define LL_BLE_US_PER_BYTE_1M 8 /*!< BLE PHY speed (LE 1M PHY). */ -#define LL_BLE_US_PER_BYTE_2M 4 /*!< BLE PHY speed (LE 2M PHY). */ -#define LL_BLE_US_PER_BYTE_CODED_S8 64 /*!< BLE PHY speed (LE Coded PHY, S=8). */ -#define LL_BLE_US_PER_BIT_CODED_S8 8 /*!< BLE PHY speed (LE Coded PHY, S=8). */ -#define LL_BLE_US_PER_BYTE_CODED_S2 16 /*!< BLE PHY speed (LE Coded PHY, S=2). */ -#define LL_BLE_US_PER_BIT_CODED_S2 2 /*!< BLE PHY speed (LE Coded PHY, S=2). */ -#define LL_BLE_TIFS_US 150 /*!< BLE inter-frame space. */ -#define LL_BLE_MAFS_US 300 /*!< BLE minimum AUX frame space. */ -#define LL_BLE_US_PER_TICK 625 /*!< Microseconds per BLE tick. */ -#define LL_BLE_TMSS_US 150 /*!< BLE minimum subevent space. */ - -#define LL_MIN_PKT_TIME_US_1M 80 /*!< Minimum packet time (i.e. empty PDU) on LE 1M PHY. */ -#define LL_MIN_PKT_TIME_US_2M 44 /*!< Minimum packet time (i.e. empty PDU) on LE 2M PHY. */ -#define LL_MIN_PKT_TIME_US_CODED_S8 720 /*!< Minimum packet time (i.e. empty PDU) on LE Coded PHY, S=8. */ -#define LL_MIN_PKT_TIME_US_CODED_S2 462 /*!< Minimum packet time (i.e. empty PDU) on LE Coded PHY, S=2. */ - -#define LL_MIN_ADV_TX_PWR_LVL -20 /*!< Minimum Tx power level for advertising. */ -#define LL_MAX_ADV_TX_PWR_LVL 10 /*!< Maximum Tx power level for advertising. */ - -#define LL_MIN_TX_PWR_LVL -30 /*!< Minimum Tx power level for connections. */ -#define LL_MAX_TX_PWR_LVL 20 /*!< Maximum Tx power level for connections. */ - -#define LL_MAX_TIFS_DEVIATION 2 /*!< Maximum TIFS deviation in microseconds. */ - -#define LL_WW_RX_DEVIATION_USEC 16 /*!< RX deviation in microseconds for window widening. */ - -#define LL_30_USEC_OFFS_MAX_USEC 245730 /*!< Maximum value for 30 microseconds offset unit in microseconds. */ - -/*** ACAD ***/ - -/*! \brief ACAD opcodes. */ -enum -{ - LL_ACAD_OPCODE_CHANNEL_MAP_UPDATE = 0x28 /*!< Opcode for acad update periodic channel map ind. */ -}; -#define LL_ACAD_OPCODE_LEN 1 /*!< Length of a single Acad opcode. */ -#define LL_INSTANT_LEN 2 /*!< Length of instant field (event counter). */ -#define LL_ACAD_LEN_FIELD_LEN 1 /*!< Length of Acad length field */ -#define LL_ACAD_CHAN_MAP_LEN 5 /*!< Length of channel map rounded to nearest byte */ - -#define LL_ACAD_DATA_FIELD_MAX_LEN LL_EXT_HDR_ACAD_MAX_LEN - LL_ACAD_OPCODE_LEN - LL_ACAD_LEN_FIELD_LEN /*!< Length of max ACAD field length without opcode and length field */ - -#define LL_ACAD_UPDATE_CHANNEL_MAP_LEN LL_ACAD_OPCODE_LEN + LL_ACAD_CHAN_MAP_LEN + LL_INSTANT_LEN /*!< Length of acad update periodic channel map data field. */ - -/*** Modify Sleep Clock Accuracy ***/ -/*! \brief Action parameter. */ -enum -{ - LL_MODIFY_SCA_MORE_ACCURATE = 0x00, /*!< Modify to more accurate clock accuracy. */ - LL_MODIFY_SCA_LESS_ACCURATE = 0x01, /*!< Modify to less accurate clock accuracy. */ - LL_MODIFY_SCA_NO_ACTION /*!< No action (Used for request sca tester command). */ -}; -#define LL_SCA_MIN_INDEX 0 /*!< Index for lowest accuracy clock. */ -#define LL_SCA_MAX_INDEX 7 /*!< Index for highest accuracy clock. */ - -#ifdef __cplusplus -}; -#endif - -#endif /* LL_DEFS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h index 918df1f0e1c..0bf0a9c793a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h @@ -1,24 +1,26 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file + * \file + * * \brief LL initialization implementation file. * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * * Initialization conditional compilation are used to control LL initialization options. * Define one or more of the following to enable roles and features. * @@ -60,7 +62,7 @@ extern "C" { #ifndef BT_VER /*! \brief Initialize default BT version. */ -#define BT_VER LL_VER_BT_CORE_SPEC_5_1 +#define BT_VER LL_VER_BT_CORE_SPEC_5_2 #endif /************************************************************************************************** @@ -94,7 +96,7 @@ uint32_t LlInitSetLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t void LlInitBbInit(void); void LlInitSchInit(void); void LlInitLlInit(void); -void LlInitChciTrInit(void); +void LlInitChciTrInit(uint16_t maxAclLen, uint16_t maxIsoLen); void LlInitLhciInit(void); void LlMathSetSeed(const uint32_t *pSeed); void LlInitLhciHandler(void); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_math.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_math.h index 7566689e342..0bc5bcad40c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_math.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_math.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link Layer math utilities. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link Layer math utilities. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #ifndef LL_MATH_H @@ -34,7 +35,7 @@ extern "C" { **************************************************************************************************/ /*! \brief Binary divide with 1,000 divisor (n[max]=7,999). */ -#define LL_MATH_DIV_10E3(n) (((n) * UINT32_C(536871)) >> 29) +#define LL_MATH_DIV_10E3(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(536871)) >> 29)) /*! \brief Binary divide with 1,000,000 divisor (n[max]=0xFFFFFFFF). */ #define LL_MATH_DIV_10E6(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(4295)) >> 32)) @@ -113,6 +114,18 @@ uint8_t LlMathGetNumBitsSet(uint64_t num); /*************************************************************************************************/ uint32_t LlMathDivideUint32(uint32_t nu32, uint32_t de32); +/*************************************************************************************************/ +/*! + * \brief Return result of a division, rounding up. + * + * \param nu32 Numerator of size 32 bits. + * \param de32 Denominator of size 32 bits. + * + * \return Result of a division. + */ +/*************************************************************************************************/ +uint32_t LlMathDivideUint32RoundUp(uint32_t nu32, uint32_t de32); + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/sch_api_ble.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/sch_api_ble.h index c61ba8bd1ff..bd8d482a63f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/sch_api_ble.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/sch_api_ble.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer scheduler interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer scheduler interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -38,6 +39,9 @@ extern "C" { /*! \brief Preferred periodicity. */ #define SCH_RM_PREF_PER_USEC 10000 +/*! \brief Lowest perferred periodicity (for cases where intervalMax < SCH_RM_PREF_PER_USEC). */ +#define SCH_RM_PREF_PER_USEC_LOWEST 5000 + /*! \brief Preferred periodicity for connections. */ #define SCH_RM_PREF_PER_CONN_USEC (SCH_RM_PREF_PER_USEC) @@ -62,21 +66,27 @@ enum /*! \brief Get reference time callback signature. */ typedef uint32_t (*GetRefTimeCb_t)(uint8_t handle, uint32_t *pDurUsec); +/*! \brief Get topology reference time callback signature. */ +typedef uint32_t (*GetTopRefTimeCb_t)(uint8_t handle); + /************************************************************************************************** Function Declarations **************************************************************************************************/ /* Resource manager */ void SchRmInit(void); -uint32_t SchRmPreferredPeriodUsec(void); uint32_t SchRmCalcCommonPeriodicityUsec(uint32_t peerPerUsec); bool_t SchRmAdd(uint8_t handle, uint8_t pref, uint32_t minUsec, uint32_t maxUsec, uint32_t durUsec, uint32_t *pInterUsec, GetRefTimeCb_t refTimeCb); bool_t SchRmStartUpdate(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint32_t perfPerUsec, uint32_t durUsec, uint32_t *pInterUsec); void SchRmCommitUpdate(uint8_t handle); void SchRmRemove(uint8_t handle); -void SchRmSetReference(uint8_t handle); uint32_t SchRmGetOffsetUsec(uint32_t maxOffsUsec, uint8_t handle, uint32_t refTime); +/* Topology manager */ +void SchTmInit(void); +void SchTmAdd(uint8_t handle, uint32_t interUsec, uint32_t durUsec, bool_t movable, GetTopRefTimeCb_t refTimeCb); +void SchTmRemove(uint8_t handle); + /* BLE time utilities */ uint32_t SchBleCalcDataPktDurationUsec(uint8_t phy, uint16_t len); uint32_t SchBleCalcAdvPktDurationUsec(uint8_t phy, uint8_t phyOptions, uint16_t len); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/bb_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/bb_api.h index 5d98e45a52d..067f7f639e5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/bb_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/bb_api.h @@ -1,24 +1,25 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! * \file + * * \brief Baseband interface file. * + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * * \addtogroup BB_API Baseband (BB) API * \{ * @@ -68,6 +69,7 @@ #include "wsf_types.h" #include "cfg_mac.h" +#include "pal_bb.h" #ifdef __cplusplus extern "C" { @@ -101,6 +103,7 @@ typedef struct /* Scheduler */ uint16_t schSetupDelayUs; /*!< Operation setup delay in microseconds. */ + uint32_t BbTimerBoundaryUs; /*!< BB timer tick boundary translated in microseconds before wraparound. */ } BbRtCfg_t; /*! \} */ /* BB_API_INIT */ @@ -120,12 +123,14 @@ typedef void (*BbBodCback_t)(struct BbOpDesc_tag *pBod); /*! \brief Protocol event callback signature. */ typedef void (*BbProtCback_t)(void); +/*! \brief Low power callback. */ +typedef void (*BbLowPowerCback_t)(void); + /*! \brief BOD rescheduling policy (listed in priority order). */ typedef enum { BB_RESCH_FIXED_PREFERRED, /*!< BOD is fixed (rescheduling has limited recoverable consequences). */ BB_RESCH_FIXED, /*!< BOD is fixed (rescheduling has recoverable consequences). */ - BB_RESCH_PERIODIC, /*!< BOD is periodic (rescheduling has consequences). */ BB_RESCH_MOVEABLE_PREFERRED, /*!< BOD is movable (rescheduling has minor consequences). */ BB_RESCH_MOVEABLE, /*!< BOD is movable (rescheduling has no consequences). */ BB_RESCH_BACKGROUND /*!< BOD is single background task. */ @@ -146,14 +151,13 @@ typedef struct BbOpDesc_tag struct BbOpDesc_tag *pPrev; /*!< Previous BOD. */ struct BbOpDesc_tag *pNext; /*!< Next BOD. */ - uint32_t due; /*!< Absolute clock due time. */ + uint32_t dueUsec; /*!< Absolute clock due time in microseconds. */ uint32_t minDurUsec; /*!< Minimum required duration in microseconds. */ uint32_t maxDurUsec; /*!< Maximum required duration in microseconds. */ - uint16_t dueOffsetUsec; /*!< Due time offset in microseconds. */ - uint8_t reschPolicy; /*!< Rescheduling policy. */ + BbReschPol_t reschPolicy:8; /*!< Rescheduling policy. */ - uint8_t protId; /*!< Protocol type. */ + PalBbProt_t protId:8; /*!< Protocol type. */ BbBodCback_t endCback; /*!< End of BOD callback (when BOD ends). */ BbBodCback_t abortCback; /*!< Abort BOD callback (when BOD is removed before beginning). */ @@ -183,8 +187,6 @@ typedef struct BbOpDesc_tag * * \param pCfg Pointer to runtime configuration parameters (data must be static). * - * \return None. - * * This function initializes the BB subsystem's runtime configuration. * * \note This routine must be called only once before any other initialization routine. @@ -196,8 +198,6 @@ void BbInitRunTimeCfg(const BbRtCfg_t *pCfg); /*! * \brief Initialize the BB. * - * \return None. - * * Initialize baseband resources. */ /*************************************************************************************************/ @@ -209,8 +209,6 @@ void BbInit(void); * * \param eventCback Event callback. * - * \return None. - * * Register operation completion handler. */ /*************************************************************************************************/ @@ -225,12 +223,20 @@ void BbRegister(BbBodCompCback_t eventCback); * \param cancelOpCback Cancel operation callback. * \param startProtCback Start protocol callback. * \param stopProtCback Stop protocol callback. + */ +/*************************************************************************************************/ +void BbRegisterProt(PalBbProt_t protId, BbBodCback_t execOpCback, BbBodCback_t cancelOpCback, + BbProtCback_t startProtCback, BbProtCback_t stopProtCback); + +/*************************************************************************************************/ +/*! + * \brief Register protocol handlers for low power. * - * \return None. + * \param protId Protocol ID. + * \param lowPowerOpCback Low power operation callback. */ /*************************************************************************************************/ -void BbRegisterProt(uint8_t protId, BbBodCback_t execOpCback, BbBodCback_t cancelOpCback, - BbProtCback_t startProtCback, BbProtCback_t stopProtCback); +void BbRegisterProtLowPower(PalBbProt_t protId, BbLowPowerCback_t lowPowerOpCback); /*! \} */ /* BB_API_INIT */ @@ -243,14 +249,12 @@ void BbRegisterProt(uint8_t protId, BbBodCback_t execOpCback, BbBodCback_t cance * * \param protId Protocol ID. * - * \return None. - * * Enable BB and start processing the list of BODs. This routine may be called several times, if * a protocol layers has several simultaneously-enabled operations. However, \ref BbStop() must * be called an equal number of time to disable the baseband. */ /*************************************************************************************************/ -void BbStart(uint8_t protId); +void BbStart(PalBbProt_t protId); /*************************************************************************************************/ /*! @@ -264,7 +268,7 @@ void BbStart(uint8_t protId); * balanced to ensure that the hardware is disabled if and only if appropriate. */ /*************************************************************************************************/ -void BbStop(uint8_t protId); +void BbStop(PalBbProt_t protId); /*************************************************************************************************/ /*! @@ -272,8 +276,6 @@ void BbStop(uint8_t protId); * * \param pBod Pointer to the BOD to execute. * - * \return None. - * * Execute the protocol specific BOD handler. */ /*************************************************************************************************/ @@ -282,8 +284,6 @@ void BbExecuteBod(BbOpDesc_t *pBod); /*************************************************************************************************/ /*! * \brief Cancel current executing BOD. - * - * \return None. */ /*************************************************************************************************/ void BbCancelBod(void); @@ -301,8 +301,6 @@ BbOpDesc_t *BbGetCurrentBod(void); /*! * \brief Set termination flag of current executing BOD. * - * \return None. - * * \note This function is expected to be called during the execution context of the * current executing BOD, typically in the related ISRs. In the end, termination * flag will help to decide if BbTerminateBod() should be called. @@ -323,8 +321,6 @@ bool_t BbGetBodTerminateFlag(void); /*! * \brief Terminate a BOD immediately. * - * \return None. - * * \note This function is expected to be called during the execution context of the * current executing BOD, typically in the related ISRs. */ @@ -342,6 +338,16 @@ void BbTerminateBod(void); /*************************************************************************************************/ uint16_t BbGetClockAccuracy(void); +/*************************************************************************************************/ +/*! + * \brief Get BB timer boundary before wraparound. + * + * \return Time boundary in microseconds. + * + */ +/*************************************************************************************************/ +uint32_t BbGetBbTimerBoundaryUs(void); + /*************************************************************************************************/ /*! * \brief Get scheduler setup delay. @@ -353,6 +359,35 @@ uint16_t BbGetClockAccuracy(void); /*************************************************************************************************/ uint16_t BbGetSchSetupDelayUs(void); +/*************************************************************************************************/ +/*! + * \brief Adjust new time tick with wraparound. + * + * \param dueUsec Time tick without wraparound in microseconds. + + * + * \return Time tick with wraparound. + * + * \note dueUsec can only be at most +/-(BbTimerBoundaryUs/2) out of range. + */ +/*************************************************************************************************/ +uint32_t BbAdjustTime(uint32_t dueUsec); + +/*************************************************************************************************/ +/*! + * \brief Get Delta between target and reference time. Only valid if target time is in the future. + * + * \param targetUsec Target time in microseconds. + * \param refUsec Reference time in microseconds. + * + * \return Positive number in microseconds if target time is in the future. + * Zero if target time is in the past or same compared with reference time. + * + * \note Caller has to make sure target time and reference time are within SCH_MAX_SPAN. + */ +/*************************************************************************************************/ +uint32_t BbGetTargetTimeDelta(uint32_t targetUsec, uint32_t refUsec); + /*************************************************************************************************/ /*! * \brief Returns the ID of the active protocol. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac.h index 3b048b84dbd..44b5660f336 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief MAC system configuration. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief MAC system configuration. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -32,12 +33,6 @@ extern "C" { Macros **************************************************************************************************/ -/*** Baseband ***/ - -#ifndef BB_CLK_RATE_HZ -#define BB_CLK_RATE_HZ 1000000 /*!< BB clock rate in hertz. */ -#endif - /*** Controller HCI ***/ #ifndef CHCI_BUF_TAILROOM @@ -45,6 +40,7 @@ extern "C" { #endif /*** Scheduler ***/ + #ifndef SCH_TIMER_REQUIRED #define SCH_TIMER_REQUIRED TRUE /*!< If hardware timer is required for radio access scheduler.*/ #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac_ble.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac_ble.h index 8704d9e3865..71c1cdd7c5a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac_ble.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/cfg_mac_ble.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief BLE MAC system configuration. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief BLE MAC system configuration. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,6 +43,10 @@ extern "C" { #define LL_MAX_CONN 4 /*!< Absolute maximum number of connections (maximum is 32). */ #endif +#ifndef LL_MAX_FRAG +#define LL_MAX_FRAG 8 /*!< Maximum number of Data PDU fragments. */ +#endif + #ifndef LL_NUM_ADV_FILT #define LL_NUM_ADV_FILT 8 /*!< Table size for advertising filter. */ #endif @@ -71,7 +76,19 @@ extern "C" { #endif #ifndef LL_MAX_CIS -#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */ +#define LL_MAX_CIS 6 /*!< Absolute maximum number of connected isochronous streams, it is shared by CIGs. */ +#endif + +#ifndef LL_MAX_BIG +#define LL_MAX_BIG 2 /*!< Absolute maximum number of broadcast isochronous groups. */ +#endif + +#ifndef LL_MAX_BIS +#define LL_MAX_BIS 6 /*!< Absolute maximum number of broadcast isochronous streams, it is shared by BIGs. */ +#endif + +#ifndef LL_MAX_BN +#define LL_MAX_BN 8 /*!< Absolute maximum number of bursts. */ #endif #ifndef LHCI_ENABLE_VS @@ -81,7 +98,7 @@ extern "C" { /*** Scheduler ***/ #ifndef SCH_RM_MAX_RSVN -#define SCH_RM_MAX_RSVN (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_CIG) /*!< Maximum number of reservations (maximum is 32). */ +#define SCH_RM_MAX_RSVN (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_CIG + LL_MAX_BIG) /*!< Maximum number of reservations (maximum is 32). */ #endif /*** Baseband ***/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_api.h index cb1f61f6419..edc4495851e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Controller HCI transport API. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Controller HCI transport API. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -46,7 +47,7 @@ enum enum { CHCI_TR_TYPE_CMD = 0, /*!< Command message (receive only). */ - CHCI_TR_TYPE_DATA, /*!< ACL data message (send or receive). */ + CHCI_TR_TYPE_ACL, /*!< ACL data message (send or receive). */ CHCI_TR_TYPE_EVT, /*!< Event message (send only). */ CHCI_TR_TYPE_ISO, /*!< ISO data message (send or receive). */ CHCI_TR_TYPE_NUM /*!< Number of types. */ @@ -55,8 +56,9 @@ enum /*! \brief Error codes. */ enum { - CHCI_TR_CODE_INVALID_DATA = 0xA0, /*!< Invalid data received. */ - CHCI_TR_CODE_OUT_OF_MEMORY = 0xA1 /*!< Out of memory. */ + CHCI_TR_CODE_INVALID_DATA = 0xA0, /*!< Invalid data received. */ + CHCI_TR_CODE_INVALID_DATA_LEN = 0xA1, /*!< Invalid data length. */ + CHCI_TR_CODE_OUT_OF_MEMORY = 0xA2 /*!< Out of memory. */ }; /*! \brief 802.15.4 protocol command type. */ @@ -101,11 +103,11 @@ typedef void (*ChciTrSendHwErrorCback_t)(uint8_t code); * \brief Initialize the transport handler. * * \param handlerId Handler ID. - * - * \return None. + * \param maxAclLen Maximum ACL data length. + * \param maxIsoSduLen Maximum ISO data length. */ /*************************************************************************************************/ -void ChciTrHandlerInit(wsfHandlerId_t handlerId); +void ChciTrHandlerInit(wsfHandlerId_t handlerId, uint16_t maxAclLen, uint16_t maxIsoSduLen); /*************************************************************************************************/ /*! @@ -113,8 +115,6 @@ void ChciTrHandlerInit(wsfHandlerId_t handlerId); * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void ChciTrHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); @@ -127,8 +127,6 @@ void ChciTrHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); * \param recvCback Message received callback. * \param sendCompleteCback Message send complete callback. * \param serviceCback Service callback. - * - * \return None. */ /*************************************************************************************************/ void ChciTrSetCbacks(uint8_t prot, ChciTrRecvCback_t recvCback, ChciTrSendCompleteCback_t sendCompleteCback, @@ -139,8 +137,6 @@ void ChciTrSetCbacks(uint8_t prot, ChciTrRecvCback_t recvCback, ChciTrSendComple * \brief Set send hardware error callback. * * \param sendHwErrorCback Send hardware error callback. - * - * \return None. */ /*************************************************************************************************/ void ChciTrSetSendHwErrorCback(ChciTrSendHwErrorCback_t sendHwErrorCback); @@ -150,8 +146,6 @@ void ChciTrSetSendHwErrorCback(ChciTrSendHwErrorCback_t sendHwErrorCback); * \brief Flag protocol for needing service. * * \param prot Protocol. - * - * \return None. */ /*************************************************************************************************/ void ChciTrNeedsService(uint8_t prot); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_tr.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_tr.h index 15bffb71fee..591e6452d73 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_tr.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/chci_tr.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Controller HCI transport interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Controller HCI transport interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,12 +38,12 @@ extern "C" { #ifndef UART_BAUD /*! \brief Default UART baud rate. */ -#define UART_BAUD 1000000 +#define UART_BAUD 1000000 #endif -#ifndef UART_DEFAULT_CONFIG_HWFC +#ifndef UART_HWFC /*! \brief Default Hardware Flow Control. */ -#define UART_DEFAULT_CONFIG_HWFC 1 +#define UART_HWFC 1 #endif /************************************************************************************************** @@ -56,12 +57,17 @@ extern "C" { * \param prot Protocol. * \param type Message type. * \param pBuf Message. - * - * \return None. */ /*************************************************************************************************/ void chciTrRecv(uint8_t prot, uint8_t type, uint8_t *pBuf); +/*************************************************************************************************/ +/*! + * \brief Signal the completion of a message transmission. + */ +/*************************************************************************************************/ +void chciTrSendComplete(void); + /*************************************************************************************************/ /*! * \brief Service the transport device. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/sch_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/sch_api.h index 4c6d7081fad..c1de5179d91 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/sch_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/common/sch_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Multi-protocol scheduler interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Multi-protocol scheduler interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -48,6 +49,8 @@ void SchInit(void); void SchHandlerInit(wsfHandlerId_t handlerId); void SchReset(void); uint16_t SchStatsGetHandlerWatermarkUsec(void); +uint16_t SchStatsGetDelayLoadWatermarkCount(void); +uint32_t SchStatsGetDelayLoadTotalCount(void); /* Control */ void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master.c index 578bdf152cd..0c584d80e03 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Scanning master BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Scanning master BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,19 +28,12 @@ #include "sch_api.h" #include "wsf_math.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Macros **************************************************************************************************/ -/*! \brief Event states for scan operations. */ -enum -{ - BB_EVT_STATE_RX_ADV_IND, - BB_EVT_STATE_TX_SCAN_OR_CONN_IND, - BB_EVT_STATE_RX_SCAN_RSP -}; - /************************************************************************************************** Global Variables **************************************************************************************************/ @@ -67,9 +61,31 @@ extern const BbRtCfg_t *pBbRtCfg; /*************************************************************************************************/ static uint32_t bbBleCalcScanDurationUsec(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan, uint32_t refTime, uint32_t setupUsec) { + BbBleData_t * const pBle = pBod->prot.pBle; + WSF_ASSERT(pBod->maxDurUsec > 0); - const uint32_t totalGapUsec = BB_SCAN_GUARD_US + setupUsec; + /* Guard time at the end of a scan window to the next BOD. */ + /* Backoff for RX of preamble and AA which are compensated in BB driver. */ + uint32_t totalGapUsec = BbGetSchSetupDelayUs() + setupUsec; + + switch (pBle->chan.rxPhy) + { + case BB_PHY_BLE_1M: + totalGapUsec += (LL_BLE_US_PER_BYTE_1M * LL_PREAMBLE_LEN_1M) + \ + (LL_BLE_US_PER_BYTE_1M * LL_AA_LEN); + break; + case BB_PHY_BLE_2M: + totalGapUsec += (LL_BLE_US_PER_BYTE_2M * LL_PREAMBLE_LEN_2M) + \ + (LL_BLE_US_PER_BYTE_2M * LL_AA_LEN); + break; + case BB_PHY_BLE_CODED: + totalGapUsec += (LL_BLE_US_PER_BIT_CODED_S8 * LL_PREAMBLE_LEN_CODED_BITS) + \ + (LL_BLE_US_PER_BYTE_CODED_S8 * LL_AA_LEN); + break; + default: + break; + } if ((pScan->elapsedUsec + totalGapUsec) > pBod->maxDurUsec) { @@ -82,7 +98,8 @@ static uint32_t bbBleCalcScanDurationUsec(BbOpDesc_t *pBod, BbBleMstAdvEvent_t * if (pBod->pNext) { - uint32_t timeToNextOpUsec = BB_TICKS_TO_US(pBod->pNext->due - refTime); + + uint32_t timeToNextOpUsec = BbGetTargetTimeDelta(pBod->pNext->dueUsec, refTime); /* Limit scanning to the edge of neighboring BOD. */ remTimeUsec = WSF_MIN(remTimeUsec, timeToNextOpUsec); @@ -123,9 +140,9 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan) return TRUE; } - uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - pScan->elapsedUsec += BB_TICKS_TO_US(curTime - bbBleCb.lastScanStart); - bbBleCb.lastScanStart = curTime; + uint32_t curTime = PalBbGetCurrentTime(); + pScan->elapsedUsec += BbGetTargetTimeDelta(curTime, bbBleCb.lastScanStartUsec); + bbBleCb.lastScanStartUsec = curTime; uint32_t scanDurUsec; @@ -134,8 +151,7 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan) return TRUE; } - bbBleCb.bbParam.due = bbBleCb.lastScanStart + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()); - bbBleCb.bbParam.dueOffsetUsec = 0; + bbBleCb.bbParam.dueUsec = BbAdjustTime(bbBleCb.lastScanStartUsec + BbGetSchSetupDelayUs()); bbBleCb.bbParam.rxTimeoutUsec = scanDurUsec; PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -143,7 +159,7 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan) if (pScan->pTxReqBuf) { - bbBleSetIfs(); /* active scan or initiating */ + bbBleSetTifs(); /* active scan or initiating */ } else { @@ -160,8 +176,6 @@ static bool_t bbContScanOp(BbOpDesc_t *pBod, BbBleMstAdvEvent_t *pScan) * * \param status Completion status. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -177,9 +191,19 @@ static void bbMstScanTxCompCback(uint8_t status) bool_t bodComplete = FALSE; bool_t bodCont = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + switch (bbBleCb.evtState++) { - case BB_EVT_STATE_TX_SCAN_OR_CONN_IND: + case BB_EVT_STATE_TX_SCAN_OR_CONN_INIT: { switch (status) { @@ -254,6 +278,17 @@ static void bbMstScanTxCompCback(uint8_t status) BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferMstScanPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbScanStats.txIsrUsec); } @@ -264,11 +299,9 @@ static void bbMstScanTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -285,6 +318,16 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint bool_t bodComplete = FALSE; bool_t bodCont = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + switch (bbBleCb.evtState++) { case BB_EVT_STATE_RX_ADV_IND: @@ -298,7 +341,7 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint pScan->advRssi = rssi; pScan->advCrc = crc; - pScan->advStartTs = timestamp; + pScan->advStartTsUsec = timestamp; pScan->advRxPhyOptions = rxPhyOptions; bool_t pduAllow = BbBlePduFiltCheck(pScan->pRxAdvBuf, &pBle->pduFilt, FALSE, &pScan->filtResults); @@ -311,7 +354,7 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint PalBbBleTxBufDesc_t desc = {.pBuf = pScan->pTxReqBuf, .len = pScan->txReqLen}; - bbBleSetIfs(); + bbBleSetTifs(); PalBbBleTxTifsData(&desc, 1); /* Tx may fail; no more important statements in the !bodComplete code path */ @@ -321,6 +364,14 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint bodCont = TRUE; } +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer here before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, pScan->pRxAdvBuf, LL_ADV_HDR_LEN); + } +#endif + if (pduAllow && pScan->rxAdvPostCback) { pScan->rxAdvPostCback(pCur, pScan->pRxAdvBuf); @@ -361,7 +412,7 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint break; } - case BB_EVT_STATE_RX_SCAN_RSP: + case BB_EVT_STATE_RX_SCAN_OR_CONN_RSP: { WSF_ASSERT(pScan->rxRspCback); WSF_ASSERT(pScan->pRxRspBuf); @@ -369,6 +420,14 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint switch (status) { case BB_STATUS_SUCCESS: +#if (BB_SNIFFER_ENABLED == TRUE) + /* If the rx was successful, pack the rx sniffer header here before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, pScan->pRxRspBuf, LL_ADV_HDR_LEN); + } +#endif + if (BbBlePduFiltCheck(pScan->pRxRspBuf, &pBle->pduFilt, FALSE, &pScan->filtResults)) { pScan->rxRspCback(pCur, pScan->pRxRspBuf); @@ -435,6 +494,19 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferMstScanPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbScanStats.rxIsrUsec); } @@ -444,8 +516,6 @@ static void bbMstScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbMstExecuteScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -459,28 +529,28 @@ static void bbMstExecuteScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) uint32_t scanDurUsec; - if ((scanDurUsec = bbBleCalcScanDurationUsec(pBod, pScan, pBod->due, 0)) == 0) + if ((scanDurUsec = bbBleCalcScanDurationUsec(pBod, pScan, pBod->dueUsec, 0)) == 0) { BbSetBodTerminateFlag(); return; } - bbBleCb.lastScanStart = pBod->due; + bbBleCb.lastScanStartUsec = pBod->dueUsec; PalBbBleSetChannelParam(&pBle->chan); bbBleCb.bbParam.txCback = bbMstScanTxCompCback; bbBleCb.bbParam.rxCback = bbMstScanRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = scanDurUsec; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; PalBbBleSetDataParams(&bbBleCb.bbParam); bbBleCb.evtState = 0; if (pScan->pTxReqBuf) { - bbBleSetIfs(); /* active scan or initiating */ + bbBleSetTifs(); /* active scan or initiating */ } else { @@ -493,16 +563,27 @@ static void bbMstExecuteScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*************************************************************************************************/ /*! - * \brief Initialize for scanning master operations. + * \brief Cancel scan BOD. * - * \return None. + * \param pBod Pointer to the BOD to execute. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbMstCancelScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + PalBbBleCancelData(); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize for scanning master operations. * * Update the operation table with scanning master operations routines. */ /*************************************************************************************************/ void BbBleScanMasterInit(void) { - bbBleRegisterOp(BB_BLE_OP_MST_ADV_EVENT, bbMstExecuteScanOp, NULL); + bbBleRegisterOp(BB_BLE_OP_MST_ADV_EVENT, bbMstExecuteScanOp, bbMstCancelScanOp); memset(&bbScanStats, 0, sizeof(bbScanStats)); } @@ -510,8 +591,6 @@ void BbBleScanMasterInit(void) /*************************************************************************************************/ /*! * \brief Get advertising packet statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetScanStats(BbBleScanPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master_ae.c index e9c677c10b3..a87da6c7cc1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_master_ae.c @@ -1,43 +1,36 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Extended scanning master BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Extended scanning master BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "bb_ble_int.h" #include "sch_api.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Macros **************************************************************************************************/ -/*! \brief Event states for scan operations. */ -enum -{ - BB_EVT_STATE_RX_ADV_IND, /*!< Receive Advertising indication. */ - BB_EVT_STATE_TX_SCAN_OR_CONN_REQ, /*!< Transmit scan or connection request. */ - BB_EVT_STATE_RX_SCAN_OR_CONN_RSP, /*!< Receive scan or connection response. */ - BB_EVT_STATE_RX_CHAIN_IND /*!< Receive chain indication. */ -}; - /************************************************************************************************** Global Variables **************************************************************************************************/ @@ -60,8 +53,6 @@ static uint8_t bbPerScanBuf[LL_EXT_ADVB_MAX_LEN]; * * \param status Completion status. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -73,9 +64,20 @@ static void bbMstAuxScanTxCompCback(uint8_t status) bool_t bodComplete = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } + BbOpDesc_t * const pCur = BbGetCurrentBod(); +#endif + switch (bbBleCb.evtState++) { - case BB_EVT_STATE_TX_SCAN_OR_CONN_REQ: + case BB_EVT_STATE_TX_SCAN_OR_CONN_INIT: { switch (status) { @@ -119,6 +121,17 @@ static void bbMstAuxScanTxCompCback(uint8_t status) BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferMstAuxScanPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAuxScanStats.txIsrUsec); } @@ -129,11 +142,9 @@ static void bbMstAuxScanTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -150,6 +161,16 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u bool_t bodComplete = FALSE; bool_t bodCont = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + switch (bbBleCb.evtState) { case BB_EVT_STATE_RX_ADV_IND: @@ -162,9 +183,17 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u pAuxScan->auxAdvRssi = rssi; pAuxScan->auxAdvCrc = crc; - pAuxScan->auxStartTs = timestamp; + pAuxScan->auxStartTsUsec = timestamp; pAuxScan->auxRxPhyOptions = rxPhyOptions; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, bbAuxAdvBuf, LL_ADV_HDR_LEN); + } +#endif + uint32_t auxOffsetUsec; if (pAuxScan->rxAuxAdvCback(pCur, bbAuxAdvBuf)) { @@ -172,13 +201,13 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u { /* Tx response PDU. */ - bbBleCb.evtState = BB_EVT_STATE_TX_SCAN_OR_CONN_REQ; + bbBleCb.evtState = BB_EVT_STATE_TX_SCAN_OR_CONN_INIT; BB_ISR_MARK(bbAuxScanStats.txSetupUsec); PalBbBleTxBufDesc_t desc = {.pBuf = pAuxScan->pTxAuxReqBuf, .len = pAuxScan->txAuxReqLen}; - bbBleSetIfs(); + bbBleSetTifs(); PalBbBleTxTifsData(&desc, 1); } } @@ -193,7 +222,7 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u PalBbBleCancelTifs(); PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(timestamp + auxOffsetUsec); PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbAuxScanStats.rxSetupUsec); @@ -261,9 +290,17 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u case BB_STATUS_SUCCESS: pAuxScan->auxAdvRssi = rssi; pAuxScan->auxAdvCrc = crc; - pAuxScan->auxStartTs = timestamp; + pAuxScan->auxStartTsUsec = timestamp; pAuxScan->auxRxPhyOptions = rxPhyOptions; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, bbAuxAdvBuf, LL_ADV_HDR_LEN); + } +#endif + uint32_t auxOffsetUsec; pAuxScan->rxAuxRspCback(pCur, bbAuxAdvBuf); @@ -271,7 +308,7 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u ((auxOffsetUsec = pAuxScan->rxAuxChainCback(pCur, bbAuxAdvBuf)) > 0)) { PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(timestamp + auxOffsetUsec); PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbAuxScanStats.rxSetupUsec); @@ -340,11 +377,19 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u { case BB_STATUS_SUCCESS: { +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, bbAuxAdvBuf, LL_ADV_HDR_LEN); + } +#endif + uint32_t auxOffsetUsec; if ((auxOffsetUsec = pAuxScan->rxAuxChainCback(pCur, bbAuxAdvBuf)) > 0) { PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(timestamp + auxOffsetUsec); PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbAuxScanStats.rxSetupUsec); @@ -436,7 +481,21 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferMstAuxScanPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAuxScanStats.rxIsrUsec); + } /*************************************************************************************************/ @@ -445,8 +504,6 @@ static void bbMstAuxScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbMstExecuteAuxScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -458,15 +515,15 @@ static void bbMstExecuteAuxScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbMstAuxScanTxCompCback; bbBleCb.bbParam.rxCback = bbMstAuxScanRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = pAuxScan->rxSyncDelayUsec; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; PalBbBleSetDataParams(&bbBleCb.bbParam); bbBleCb.evtState = 0; if (pAuxScan->pTxAuxReqBuf) { - bbBleSetIfs(); /* active scan or initiating */ + bbBleSetTifs(); /* active scan or initiating */ } else { @@ -482,11 +539,9 @@ static void bbMstExecuteAuxScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -503,6 +558,16 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u bool_t bodComplete = FALSE; bool_t bodCont = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + switch (bbBleCb.evtState) { case BB_EVT_STATE_RX_ADV_IND: @@ -517,16 +582,24 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u bbBleCb.evtState = BB_EVT_STATE_RX_CHAIN_IND; pPerScan->perAdvRssi = rssi; pPerScan->perAdvCrc = crc; - pPerScan->perStartTs = timestamp; + pPerScan->perStartTsUsec = timestamp; pPerScan->perIsFirstTs = TRUE; pPerScan->perRxPhyOptions = rxPhyOptions; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, bbPerScanBuf, LL_ADV_HDR_LEN); + } +#endif + uint32_t auxOffsetUsec; if ((auxOffsetUsec = pPerScan->rxPerAdvCback(pCur, bbPerScanBuf, status)) > 0) { PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(timestamp + auxOffsetUsec); PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbPerScanStats.rxSetupUsec); @@ -592,11 +665,19 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u pPerScan->perAdvRssi = rssi; pPerScan->perRxPhyOptions = rxPhyOptions; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, bbPerScanBuf, LL_ADV_HDR_LEN); + } +#endif + if ((auxOffsetUsec = pPerScan->rxPerAdvCback(pCur, bbPerScanBuf, status)) > 0) { /* Continue BOD with the CHAIN_IND and adjust the channel parameters. */ PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = timestamp + BB_US_TO_BB_TICKS(auxOffsetUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(timestamp + auxOffsetUsec); PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbPerScanStats.rxSetupUsec); @@ -680,6 +761,19 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferMstPerScanPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbPerScanStats.rxIsrUsec); } @@ -689,8 +783,6 @@ static void bbMstPerScanRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, u * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbMstExecutePerScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -701,8 +793,8 @@ static void bbMstExecutePerScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.rxCback = bbMstPerScanRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = pPerScan->rxSyncDelayUsec; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; PalBbBleSetDataParams(&bbBleCb.bbParam); bbBleCb.evtState = 0; @@ -716,8 +808,6 @@ static void bbMstExecutePerScanOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for scanning master operations. * - * \return None. - * * Update the operation table with scanning master operations routines. */ /*************************************************************************************************/ @@ -733,8 +823,6 @@ void BbBleAuxScanMasterInit(void) * \brief Get advertising packet statistics. * * \param pStats Auxiliary scan statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAuxScanStats(BbBleAuxScanPktStats_t *pStats) @@ -746,8 +834,6 @@ void BbBleGetAuxScanStats(BbBleAuxScanPktStats_t *pStats) /*! * \brief Initialize for periodic scanning master operations. * - * \return None. - * * Update the operation table with periodic scanning master operations routines. */ /*************************************************************************************************/ @@ -763,8 +849,6 @@ void BbBlePerScanMasterInit(void) * \brief Get periodic scanning packet statistics. * * \param pStats periodic scan statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetPerScanStats(BbBlePerScanPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave.c index 0913760b682..32053c4dc06 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Advertising slave BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Advertising slave BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,17 +30,11 @@ #include "ll_api.h" #include "lmgr_api_adv_slave.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Macros **************************************************************************************************/ -/*! \brief Event states for advertising operations. */ -enum -{ - BB_EVT_STATE_TX_ADV_IND, /*!< Transmit Advertising PDU. */ - BB_EVT_STATE_RX_SCAN_OR_CONN_IND, /*!< Receive scan or connection indication. */ - BB_EVT_STATE_TX_SCAN_RSP /*!< Transmit scan response. */ -}; /************************************************************************************************** Global Variables @@ -82,7 +77,10 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s return TRUE; } - bbBleCb.advChIdx = bbBleCb.advChIdx % LL_NUM_CHAN_ADV; + /* Optimized calculation: advChIdx = advChIdx % LL_NUM_CHAN_ADV */ + bbBleCb.advChIdx = (bbBleCb.advChIdx < LL_NUM_CHAN_ADV) ? + bbBleCb.advChIdx : (bbBleCb.advChIdx - LL_NUM_CHAN_ADV); + pBle->chan.chanIdx = LL_CHAN_ADV_MIN_IDX + bbBleCb.advChIdx; bbBleCb.numChUsed++; @@ -107,22 +105,23 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s if (firstOpInSet) { - bbBleCb.bbParam.due = pBod->due; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; } else { if (pAdv->pRxReqBuf) { /* Schedule with relative frame gap. */ - bbBleCb.bbParam.due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()); + bbBleCb.bbParam.dueUsec = BbAdjustTime(PalBbGetCurrentTime() + BbGetSchSetupDelayUs()); } else { /* Schedule with absolute frame gap. */ - uint32_t advGap = (BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pAdv->txAdvLen)) + - BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs())); - - bbBleCb.bbParam.due += SchBleGetAlignedAuxOffsUsec(advGap); + uint32_t advGap = SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pAdv->txAdvLen) + + BbGetSchSetupDelayUs(); + uint32_t auxOffsUsec = SchBleGetAlignedAuxOffsUsec(advGap); + bbBleCb.bbParam.dueUsec = BbAdjustTime(bbBleCb.bbParam.dueUsec + auxOffsUsec); } } @@ -130,14 +129,14 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s if (pAdv->txAdvSetupCback) { - pAdv->txAdvSetupCback(pBod, bbBleCb.bbParam.due); + pAdv->txAdvSetupCback(pBod, BbAdjustTime(bbBleCb.bbParam.dueUsec)); } PalBbBleSetDataParams(&bbBleCb.bbParam); if (pAdv->pRxReqBuf) { - bbBleSetIfs(); /* scannable or connectable advertising */ + bbBleSetTifs(); /* scannable or connectable advertising */ } else { @@ -146,7 +145,7 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s PalBbBleTxBufDesc_t desc = {.pBuf = pAdv->pTxAdvBuf, .len = pAdv->txAdvLen}; PalBbBleTxData(&desc, 1); - /* Tx may fail; no more important statements in the FALSE code path */ + /* Tx may fail; no more important statements in the FALSE code path. */ return FALSE; } @@ -157,8 +156,6 @@ static bool_t bbSetupAdvOp(BbOpDesc_t *pBod, BbBleSlvAdvEvent_t *pAdv, uint8_t s * * \param status Completion status. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -173,6 +170,21 @@ static void bbSlvAdvTxCompCback(uint8_t status) bool_t bodComplete = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + BbBleData_t * const pBle = pCur->prot.pBle; + + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } + + /* Save channel before it is overwritten. */ + bbSnifferCtx.chanIdx = pBle->chan.chanIdx; +#endif + if (status != BB_STATUS_SUCCESS) { BB_INC_STAT(bbAdvStats.errAdv); @@ -187,7 +199,7 @@ static void bbSlvAdvTxCompCback(uint8_t status) { BB_ISR_MARK(bbAdvStats.rxSetupUsec); - bbBleSetIfs(); /* set up for Tx SCAN_RSP */ + bbBleSetTifs(); /* set up for Tx SCAN_RSP */ PalBbBleRxTifsData(pAdv->pRxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */ } else @@ -199,7 +211,7 @@ static void bbSlvAdvTxCompCback(uint8_t status) BB_INC_STAT(bbAdvStats.txAdv); break; - case BB_EVT_STATE_TX_SCAN_RSP: + case BB_EVT_STATE_TX_SCAN_OR_CONN_RSP: /* Operation completed. */ bodComplete = bbSetupAdvOp(pCur, pAdv, status, FALSE); BB_INC_STAT(bbAdvStats.txRsp); @@ -229,6 +241,17 @@ static void bbSlvAdvTxCompCback(uint8_t status) BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferSlvAdvPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAdvStats.txIsrUsec); } @@ -239,11 +262,9 @@ static void bbSlvAdvTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -259,9 +280,22 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3 bool_t bodComplete = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } + + /* Save channel before it is overwritten. */ + bbSnifferCtx.chanIdx = pBle->chan.chanIdx; +#endif + switch (bbBleCb.evtState++) { - case BB_EVT_STATE_RX_SCAN_OR_CONN_IND: + case BB_EVT_STATE_RX_SCAN_OR_CONN_INIT: switch (status) { case BB_STATUS_SUCCESS: @@ -269,7 +303,15 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3 WSF_ASSERT(pAdv->rxReqCback); WSF_ASSERT(pAdv->pRxReqBuf); - pAdv->reqStartTs = timestamp; + pAdv->reqStartTsUsec = timestamp; + +#if (BB_SNIFFER_ENABLED == TRUE) + /* If the rx was successful, pack the rx buffer here before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, pAdv->pRxReqBuf, LL_ADV_HDR_LEN); + } +#endif bool_t pduAllow = BbBlePduFiltCheck(pAdv->pRxReqBuf, &pBle->pduFilt, FALSE, &pAdv->filtResults); if (pduAllow && pAdv->rxReqCback(pCur, pAdv->pRxReqBuf)) @@ -346,6 +388,19 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3 BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferSlvAdvPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAdvStats.rxIsrUsec); } @@ -355,8 +410,6 @@ static void bbSlvAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint3 * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecuteAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -366,7 +419,6 @@ static void bbSlvExecuteAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbSlvAdvTxCompCback; bbBleCb.bbParam.rxCback = bbSlvAdvRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION; - bbBleCb.bbParam.dueOffsetUsec = 0; bbBleCb.evtState = 0; bbBleCb.numChUsed = 0; bbBleCb.advChIdx = pAdv->firstAdvChIdx; @@ -383,8 +435,6 @@ static void bbSlvExecuteAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to cancel. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvCancelAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -396,8 +446,6 @@ static void bbSlvCancelAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for advertising slave operations. * - * \return None. - * * Update the operation table with advertising slave operations routines. */ /*************************************************************************************************/ @@ -411,8 +459,6 @@ void BbBleAdvSlaveInit(void) /*************************************************************************************************/ /*! * \brief Get advertising packet statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAdvStats(BbBleAdvPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave_ae.c index b2ebd150046..0d672ed3fe4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_adv_slave_ae.c @@ -1,27 +1,29 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Extended advertising slave BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Extended advertising slave BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "bb_ble_int.h" +#include "bb_ble_sniffer_api.h" #include "sch_api.h" #include "sch_api_ble.h" #include @@ -30,21 +32,11 @@ Macros **************************************************************************************************/ -/*! \brief Event states for advertising operations. */ -enum -{ - BB_EVT_STATE_TX_ADV_IND, /*!< Transmit Advertising indication. */ - BB_EVT_STATE_RX_SCAN_OR_CONN_REQ, /*!< Receive scan or connection request. */ - BB_EVT_STATE_TX_SCAN_RSP, /*!< Transmit scan response. */ - BB_EVT_STATE_TX_CHAIN_IND /*!< Transmit chain indication. */ -}; - - /************************************************************************************************** Global Variables **************************************************************************************************/ -BbBleAuxAdvPktStats_t bbAuxAdvStats;/*!< Auxiliary advertising packet statistics. */ +BbBleAuxAdvPktStats_t bbAuxAdvStats; /*!< Auxiliary advertising packet statistics. */ /*************************************************************************************************/ /*! @@ -65,6 +57,7 @@ static bool_t bbSlvAdvSetupTxAuxChainInd(BbOpDesc_t *pCur, BbBleSlvAuxAdvEvent_t } uint32_t auxOffsUsec = pAuxAdv->txAuxSetupCback(pCur, TRUE); + if (auxOffsUsec == 0) { /* Operation completed. */ @@ -75,7 +68,8 @@ static bool_t bbSlvAdvSetupTxAuxChainInd(BbOpDesc_t *pCur, BbBleSlvAuxAdvEvent_t PalBbBleSetChannelParam(&pCur->prot.pBle->chan); /* Offset may be up to 1 unit earlier than actual transmission. */ - bbBleCb.bbParam.due += BB_US_TO_BB_TICKS(auxOffsUsec); + bbBleCb.bbParam.dueUsec = BbAdjustTime(bbBleCb.bbParam.dueUsec + auxOffsUsec); + PalBbBleSetDataParams(&bbBleCb.bbParam); BB_ISR_MARK(bbAuxAdvStats.rxSetupUsec); @@ -92,8 +86,6 @@ static bool_t bbSlvAdvSetupTxAuxChainInd(BbOpDesc_t *pCur, BbBleSlvAuxAdvEvent_t * * \param status Completion status. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -109,6 +101,16 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status) bool_t bodComplete = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + if (status != BB_STATUS_SUCCESS) { BB_INC_STAT(bbAuxAdvStats.errAdv); @@ -119,6 +121,14 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status) switch (bbBleCb.evtState) { case BB_EVT_STATE_TX_ADV_IND: +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + /* Save buffer to sniffer packet before it is overwritten. */ + memcpy(pPkt->pktType.advPkt.hdr, pAuxAdv->txAuxAdvPdu->pBuf, LL_ADV_HDR_LEN); + } +#endif + if (!pAuxAdv->pRxAuxReqBuf) { /* Non-connectable and non-scannable operation. */ @@ -128,24 +138,32 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status) else { /* Scannable or connectable operation. */ - bbBleCb.evtState = BB_EVT_STATE_RX_SCAN_OR_CONN_REQ; + bbBleCb.evtState = BB_EVT_STATE_RX_SCAN_OR_CONN_INIT; BB_ISR_MARK(bbAuxAdvStats.rxSetupUsec); - bbBleSetIfs(); /* set up for Tx SCAN_RSP */ + bbBleSetTifs(); /* set up for Tx SCAN_RSP */ PalBbBleRxTifsData(pAuxAdv->pRxAuxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */ } BB_INC_STAT(bbAuxAdvStats.txAdv); break; - case BB_EVT_STATE_TX_SCAN_RSP: + case BB_EVT_STATE_TX_SCAN_OR_CONN_RSP: bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND; - bbBleCb.bbParam.due = pAuxAdv->auxReqStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_SCAN_REQ_PDU_LEN)) + - BB_US_TO_BB_TICKS(LL_BLE_TIFS_US); + bbBleCb.bbParam.dueUsec = BbAdjustTime(pAuxAdv->auxReqStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_SCAN_REQ_PDU_LEN) + + LL_BLE_TIFS_US); bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv); BB_INC_STAT(bbAuxAdvStats.txRsp); break; case BB_EVT_STATE_TX_CHAIN_IND: +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + /* Save buffer to sniffer packet before it is overwritten. */ + memcpy(pPkt->pktType.advPkt.hdr, pAuxAdv->txAuxChainPdu->pBuf, LL_ADV_HDR_LEN); + } +#endif + /* bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND; */ /* Same state. */ bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv); BB_INC_STAT(bbAuxAdvStats.txChain); @@ -175,6 +193,18 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status) BbTerminateBod(); } + +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferSlvAuxAdvPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAuxAdvStats.txIsrUsec); } @@ -185,11 +215,9 @@ static void bbSlvAuxAdvTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -204,18 +232,36 @@ static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, ui bool_t bodComplete = FALSE; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Save evtState to be used later in packet forwarding. */ + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + switch (bbBleCb.evtState++) { - case BB_EVT_STATE_RX_SCAN_OR_CONN_REQ: + case BB_EVT_STATE_RX_SCAN_OR_CONN_INIT: switch (status) { case BB_STATUS_SUCCESS: WSF_ASSERT(pAuxAdv->rxAuxReqCback); WSF_ASSERT(pAuxAdv->pRxAuxReqBuf); - pAuxAdv->auxReqStartTs = timestamp; + pAuxAdv->auxReqStartTsUsec = timestamp; pAuxAdv->auxRxPhyOptions = rxPhyOptions; +#if (BB_SNIFFER_ENABLED == TRUE) + /* Pack the rx buffer before it is overwritten. */ + if (pPkt) + { + memcpy(pPkt->pktType.advPkt.hdr, pAuxAdv->pRxAuxReqBuf, LL_ADV_HDR_LEN); + } +#endif + if (pAuxAdv->rxAuxReqCback(pCur, pAuxAdv->pRxAuxReqBuf)) { BB_ISR_MARK(bbAuxAdvStats.txSetupUsec); @@ -286,6 +332,19 @@ static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, ui BbTerminateBod(); } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.status = status; + pPkt->pktType.meta.state = evtState; + + bbBleSnifferSlvAuxAdvPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbAuxAdvStats.rxIsrUsec); } @@ -295,8 +354,6 @@ static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, ui * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -306,7 +363,6 @@ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbSlvAuxAdvTxCompCback; bbBleCb.bbParam.rxCback = bbSlvAuxAdvRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION; - bbBleCb.bbParam.dueOffsetUsec = 0; bbBleCb.advChIdx = 0; bbBleCb.evtState = 0; @@ -325,14 +381,15 @@ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = pBod->due; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; bbBleCb.evtState = BB_EVT_STATE_TX_ADV_IND; PalBbBleSetDataParams(&bbBleCb.bbParam); if (pAuxAdv->pRxAuxReqBuf) { /* Request expected (scannable or connectable operation). */ - bbBleSetIfs(); + bbBleSetTifs(); } else { @@ -349,8 +406,6 @@ static void bbSlvExecuteAuxAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -360,7 +415,6 @@ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbSlvAuxAdvTxCompCback; bbBleCb.bbParam.rxCback = bbSlvAuxAdvRxCompCback; bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION; - bbBleCb.bbParam.dueOffsetUsec = 0; bbBleCb.advChIdx = 0; bbBleCb.evtState = 0; @@ -379,14 +433,15 @@ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) PalBbBleSetChannelParam(&pBle->chan); - bbBleCb.bbParam.due = pBod->due; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; bbBleCb.evtState = BB_EVT_STATE_TX_ADV_IND; PalBbBleSetDataParams(&bbBleCb.bbParam); if (pAuxAdv->pRxAuxReqBuf) { /* Request expected (scannable or connectable operation). */ - bbBleSetIfs(); + bbBleSetTifs(); } else { @@ -401,8 +456,6 @@ static void bbSlvExecutePerAdvOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for advertising slave operations. * - * \return None. - * * Update the operation table with advertising slave operations routines. */ /*************************************************************************************************/ @@ -418,8 +471,6 @@ void BbBleAuxAdvSlaveInit(void) * \brief Get auxiliary advertising packet statistics. * * \param pStats Auxiliary advertising statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetAuxAdvStats(BbBleAuxAdvPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_master.c new file mode 100644 index 00000000000..76c4098f4e5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_master.c @@ -0,0 +1,201 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief BIG master baseband porting implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_api.h" +#include "bb_ble_api.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/* Combine BIS statistics; use instantiation in bb_ble_bis_slave.c. */ +extern BbBleDataPktStats_t bbBisStats; /*!< BIS packet statistics. */ + +/*************************************************************************************************/ +/*! + * \brief Rx completion for BIS master operation. + * + * \param status Completion status. + * \param rssi RSSI value. + * \param crc CRC value. + * \param timestamp Start of packet timestamp in microseconds. + * \param rxPhyOptions Rx PHY options. + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbMstBisRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_t timestamp, uint8_t rxPhyOptions) +{ + BB_ISR_START(); + + bbBleCb.evtState += 1; + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleMstBisEvent_t * const pBis = &pCur->prot.pBle->op.mstBis; + + /* Store initial Rx timestamp, regardless of receive status. */ + pBis->startTsUsec = timestamp; + + WSF_ASSERT(bbBleCb.pRxDataBuf); + uint8_t *pBuf = bbBleCb.pRxDataBuf; + bbBleCb.pRxDataBuf = NULL; + + pBis->rxDataCback(pCur, pBuf, status); + + if (BbGetBodTerminateFlag()) + { + PalBbBleCancelTifs(); + BbTerminateBod(); + } + + /* Update statistics. */ + switch (status) + { + case BB_STATUS_SUCCESS: + BB_INC_STAT(bbBisStats.rxData); + break; + case BB_STATUS_RX_TIMEOUT: + BB_INC_STAT(bbBisStats.rxDataTimeout); + break; + case BB_STATUS_CRC_FAILED: + BB_INC_STAT(bbBisStats.rxDataCrc); + break; + case BB_STATUS_FAILED: + default: + BB_INC_STAT(bbBisStats.errData); + break; + } + + BB_ISR_MARK(bbBisStats.rxIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Cancel BIS master BOD. + * + * \param pBod Pointer to the BOD to cancel. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbMstCancelBisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + PalBbBleCancelData(); +} + +/*************************************************************************************************/ +/*! + * \brief Execute BIS master BOD. + * + * \param pBod Pointer to the BOD to execute. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbMstExecuteBisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + BbBleMstBisEvent_t * const pBis = &pBod->prot.pBle->op.mstBis; + + PalBbBleSetChannelParam(&pBle->chan); + + /* bbBleCb.bbParam.txCback = NULL; */ /* Unused */ + bbBleCb.bbParam.rxCback = bbMstBisRxCompCback; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + bbBleCb.bbParam.rxTimeoutUsec = pBis->rxSyncDelayUsec; + PalBbBleSetDataParams(&bbBleCb.bbParam); + + bbBleCb.evtState = 0; + + pBis->execCback(pBod); + + if (BbGetBodTerminateFlag() && /* Client signaled cancel. */ + BbGetCurrentBod()) /* Termination still pending. */ + { + BbTerminateBod(); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize for BIS master operations. + * + * Update the operation table with BIS master operations routines. + */ +/*************************************************************************************************/ +void BbBleBisMasterInit(void) +{ + bbBleRegisterOp(BB_BLE_OP_MST_BIS_EVENT, bbMstExecuteBisOp, bbMstCancelBisOp); + + memset(&bbBisStats, 0, sizeof(bbBisStats)); +} + +/*************************************************************************************************/ +/*! + * \brief Set receive BIS Data PDU buffer for next receive slot. + * + * \param pBuf Receive data buffer. + * \param len Maximum length of data buffer. + * \param nextPduTime Next PDU time. + * \param pNextChan Next PDU channel. + * \param reAcq Rx train re-acquisition required. + */ +/*************************************************************************************************/ +void BbBleBisRxData(uint8_t *pBuf, uint16_t len, uint32_t nextPduTime, PalBbBleChan_t *pNextChan, bool_t reAcq) +{ + WSF_ASSERT(!bbBleCb.pRxDataBuf); + + bbBleCb.pRxDataBuf = pBuf; + bbBleCb.rxDataLen = len; + + bbBleSetAbsIfs(nextPduTime, pNextChan); + + if ((bbBleCb.evtState == 0) || reAcq) + { + PalBbBleRxData(pBuf, len); + } + else + { + BB_ISR_MARK(bbBisStats.rxSetupUsec); + PalBbBleRxTifsData(pBuf, len); + } +} + +/*************************************************************************************************/ +/*! + * \brief Receive data re-acquisition. + * + * \param syncTime Due time for the next Rx operation. + * + * Update due time for next Rx operation. Called after a missed Rx operation for re-acquisition + * of the receive train. + */ +/*************************************************************************************************/ +void BbBleBisRxDataReAcq(uint32_t syncTime, PalBbBleChan_t *pChan) +{ + PalBbBleCancelTifs(); + bbBleCb.bbParam.dueUsec = syncTime; + PalBbBleSetChannelParam(pChan); + PalBbBleSetDataParams(&bbBleCb.bbParam); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_slave.c new file mode 100644 index 00000000000..d232cf6e3c1 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_bis_slave.c @@ -0,0 +1,151 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief BIG slave baseband porting implementation file. + * + * Copyright (c) 2019 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_api.h" +#include "bb_ble_api.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +BbBleDataPktStats_t bbBisStats; /*!< BIS packet statistics. */ + +/*************************************************************************************************/ +/*! + * \brief Tx completion for BIS slave operation. + * + * \param status Completion status. + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbSlvBisTxCompCback(uint8_t status) +{ + BB_ISR_START(); + + bbBleCb.evtState += 1; + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleSlvBisEvent_t * const pBis = &pCur->prot.pBle->op.slvBis; + + pBis->txDataCback(pCur, status); + BB_INC_STAT(bbBisStats.txData); + + if (BbGetBodTerminateFlag()) + { + PalBbBleCancelTifs(); + BbTerminateBod(); + } + + BB_ISR_MARK(bbBisStats.txIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Cancel BIS slave BOD. + * + * \param pBod Pointer to the BOD to cancel. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbSlvCancelBisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + PalBbBleCancelData(); +} + +/*************************************************************************************************/ +/*! + * \brief Execute BIS slave BOD. + * + * \param pBod Pointer to the BOD to execute. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbSlvExecuteBisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + BbBleSlvBisEvent_t * const pBis = &pBod->prot.pBle->op.slvBis; + + PalBbBleSetChannelParam(&pBle->chan); + + bbBleCb.bbParam.txCback = bbSlvBisTxCompCback; + /* bbBleCb.bbParam.rxCback = NULL; */ /* Unused */ + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; + /* bbBleCb.bbParam.rxTimeoutUsec = 0; */ /* Unused */ + PalBbBleSetDataParams(&bbBleCb.bbParam); + + bbBleCb.evtState = 0; + + pBis->execCback(pBod); + + if (BbGetBodTerminateFlag() && /* Client signaled cancel. */ + BbGetCurrentBod()) /* Termination still pending. */ + { + BbTerminateBod(); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize for BIS slave operations. + * + * Update the operation table with BIS slave operations routines. + */ +/*************************************************************************************************/ +void BbBleBisSlaveInit(void) +{ + bbBleRegisterOp(BB_BLE_OP_SLV_BIS_EVENT, bbSlvExecuteBisOp, bbSlvCancelBisOp); + + memset(&bbBisStats, 0, sizeof(bbBisStats)); +} + +/*************************************************************************************************/ +/*! + * \brief Transmit BIS Data PDU at next transmit slot. + * + * \param descs Array of transmit buffer descriptor. + * \param cnt Number of descriptors. + * \param nextPduTime Next PDU time. + * \param pNextChan Next PDU channel. + */ +/*************************************************************************************************/ +void BbBleBisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt, uint32_t nextPduTime, PalBbBleChan_t *pNextChan) +{ + bbBleSetAbsIfs(nextPduTime, pNextChan); + + if (bbBleCb.evtState == 0) + { + PalBbBleTxData(descs, cnt); + } + else + { + BB_ISR_MARK(bbBisStats.txSetupUsec); + PalBbBleTxTifsData(descs, cnt); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis.c new file mode 100644 index 00000000000..472dd1b9b16 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis.c @@ -0,0 +1,104 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Connected isochronous stream baseband porting implementation file. + * + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_api.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +BbBleDataPktStats_t bbCisStats; /*!< CIS packet statistics. */ + +/*************************************************************************************************/ +/*! + * \brief Transmit data PDU at next transmit slot. + * + * \param descs Array of transmit buffer descriptor. + * \param cnt Number of descriptors. + * + * \note This function is expected to be called during the call context of + * \ref BbBleMstCisEvent_t::rxDataCback or \ref BbBleSlvCisEvent_t::rxDataCback + * callback routine. + */ +/*************************************************************************************************/ +void BbBleCisTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) +{ + if ((BbGetCurrentBod()->prot.pBle->chan.opType == BB_BLE_OP_MST_CIS_EVENT) && + (bbBleCb.evtState == 0)) + { + bbBleSetTifs(); /* master always Rx's after Tx */ + PalBbBleTxData(descs, cnt); + } + else + { + BB_ISR_MARK(bbCisStats.txSetupUsec); + /* TODO set only if master or if slave and Rx may follow in CE. */ + bbBleSetTifs(); + PalBbBleTxTifsData(descs, cnt); + } +} + +/*************************************************************************************************/ +/*! + * \brief Set receive data buffer for next receive slot. + * + * \param pBuf Receive data buffer. + * \param len Maximum length of data buffer. + * + * \note This function is expected to be called during the call context of + * \ref BbBleMstCisEvent_t::rxDataCback or + * \ref BbBleSlvCisEvent_t::rxDataCback callback routine. + * + * \note BB must always call the \ref BbBleMstCisEvent_t::rxDataCback or + * \ref BbBleSlvCisEvent_t::rxDataCback callback routine of the + * currently executing BOD with the given buffer. + */ +/*************************************************************************************************/ +void BbBleCisRxData(uint8_t *pBuf, uint16_t len) +{ + WSF_ASSERT(!bbBleCb.pRxCisDataBuf); + + bbBleCb.pRxCisDataBuf = pBuf; + bbBleCb.rxCisDataLen = len; + + if ((BbGetCurrentBod()->prot.pBle->chan.opType == BB_BLE_OP_SLV_CIS_EVENT) && + (bbBleCb.evtState == 0)) + { + bbBleSetTifs(); /* slave always Tx's after Rx */ + PalBbBleRxData(pBuf, len); + } +} + +/*************************************************************************************************/ +/*! + * \brief Get connection packet statistics. + */ +/*************************************************************************************************/ +void BbBleGetCisStats(BbBleDataPktStats_t *pStats) +{ + *pStats = bbCisStats; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_master.c new file mode 100644 index 00000000000..f259fce35df --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_master.c @@ -0,0 +1,344 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Connected isochronous stream master baseband porting implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_api.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Event states for scan operations. */ +enum +{ + BB_EVT_STATE_IDLE, /*!< Idle state. */ + BB_EVT_STATE_TERMINATING, /*!< BOD terminating state. */ +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +extern BbBleDataPktStats_t bbCisStats; /*!< CIS packet statistics. */ + +/*************************************************************************************************/ +/*! + * \brief Check whether to continue next operation or not. + * + * \param pCur Current BOD. + * \param pCis Master CIS event. + * \param pNewCisCtx TRUE if switch to a new CIS context. + * + * \return TRUE if operation completed; FALSE if it continues. + */ +/*************************************************************************************************/ +static bool_t bbMstCisCheckContOp(BbOpDesc_t *pCur, BbBleMstCisEvent_t *pCis, bool_t *pNewCisCtx) +{ + if (BbGetBodTerminateFlag()) + { + return TRUE; + } + + /* Update new channel index and due time. */ + uint32_t offsUsec = pCis->checkContOpCback(pCur, pNewCisCtx); + + if (offsUsec == 0) + { + /* Operation completed. */ + return TRUE; + } + + /* Updated channel parameter. */ + BbBleData_t *pBle = pCur->prot.pBle; + PalBbBleSetChannelParam(&pBle->chan); + + /* Updated due time and data parameters. */ + bbBleCb.bbParam.dueUsec = BbAdjustTime(bbBleCb.bbParam.dueUsec + offsUsec); + PalBbBleSetDataParams(&bbBleCb.bbParam); + + /* Update the header field and start Tx. */ + pCis->contExecCback(pCur); + + /* Operation continues. */ + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Post subevent operation activities. + * + * \param pCur Current BOD. + * \param pCis Master CIS event. + * \param status Baseband status code. + */ +/*************************************************************************************************/ +static void bbMstCisPostSubEvt(BbOpDesc_t *pCur, BbBleMstCisEvent_t *pCis, uint8_t status) +{ + /* Calculate the next sub-event channel index and also setup Rx resource. */ + pCis->postSubEvtCback(pCur, status); +} + +/*************************************************************************************************/ +/*! + * \brief Tx completion for CIS master operation. + * + * \param status Transmission status + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbMstCisTxCompCback(uint8_t status) +{ + BB_ISR_START(); + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleMstCisEvent_t * const pCis = &pCur->prot.pBle->op.mstCis; + + pCis->txDataCback(pCur, status); + + if (bbBleCb.pRxCisDataBuf && + (status == BB_STATUS_SUCCESS)) + { + BB_ISR_MARK(bbCisStats.rxSetupUsec); + + bbBleSetTifs(); /* TODO set only if Tx may follow in CE */ + PalBbBleRxTifsData(bbBleCb.pRxCisDataBuf, bbBleCb.rxDataLen); + } + else + { + /* Cancel TIFS timer if active. */ + switch (status) + { + case BB_STATUS_SUCCESS: + PalBbBleCancelTifs(); + break; + case BB_STATUS_FAILED: + default: + /* Free Rx data buffer before BOD end. */ + if (bbBleCb.pRxCisDataBuf != NULL) /* buffer should always exist, but still check */ + { + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + pCis->rxDataCback(pCur, pBuf, BB_STATUS_CANCELED); + } + break; + } + + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + + /* Update statistics. */ + switch (status) + { + case BB_STATUS_SUCCESS: + BB_INC_STAT(bbCisStats.txData); + break; + case BB_STATUS_FAILED: + default: + BB_INC_STAT(bbCisStats.errData); + break; + } + + BB_ISR_MARK(bbCisStats.txIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Rx completion for CIS master operation. + * + * \param status Reception status. + * \param rssi RSSI value. + * \param crc CRC value. + * \param timestamp Start of packet timestamp in microseconds. + * \param rxPhyOptions Rx PHY options. + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbMstCisRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_t timestamp, uint8_t rxPhyOptions) +{ + BB_ISR_START(); + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleMstCisEvent_t * const pCis = &pCur->prot.pBle->op.mstCis; + bool_t bodComplete = FALSE; + bool_t newCisCtx = FALSE; + + pCis->rssi = rssi; + pCis->rxPhyOptions = rxPhyOptions; + + WSF_ASSERT(bbBleCb.pRxCisDataBuf); + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + + pCis->rxDataCback(pCur, pBuf, status); + + /* If continue current operation, need to setup the channel parameter here. */ + bodComplete = bbMstCisCheckContOp(pCur, pCis, &newCisCtx); + + if (BbGetBodTerminateFlag() || bodComplete) + { + WSF_ASSERT(!bbBleCb.pRxCisDataBuf); + + /* Cancel TIFS timer if active. */ + switch (status) + { + case BB_STATUS_SUCCESS: + case BB_STATUS_CRC_FAILED: + PalBbBleCancelTifs(); + break; + default: + break; + } + + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + + /* Skip the post subevent callback if switching to the new CIS context. */ + if (newCisCtx == FALSE) + { + bbMstCisPostSubEvt(pCur, pCis, status); + } + + /* Update statistics. */ + switch (status) + { + case BB_STATUS_SUCCESS: + BB_INC_STAT(bbCisStats.rxData); + break; + case BB_STATUS_RX_TIMEOUT: + BB_INC_STAT(bbCisStats.rxDataTimeout); + break; + case BB_STATUS_CRC_FAILED: + BB_INC_STAT(bbCisStats.rxDataCrc); + break; + case BB_STATUS_FAILED: + default: + BB_INC_STAT(bbCisStats.errData); + break; + } + + BB_ISR_MARK(bbCisStats.rxIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Execute CIS master BOD. + * + * \param pBod Pointer to the BOD to execute. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbMstExecuteCisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + BbBleMstCisEvent_t * const pCis = &pBod->prot.pBle->op.mstCis; + + if (BbGetBodTerminateFlag()) + { + /* Client terminated. */ + return; + } + + WSF_ASSERT(pBle->op.mstCis.txDataCback); + WSF_ASSERT(pBle->op.mstCis.rxDataCback); + WSF_ASSERT(pBle->op.mstCis.execCback); + WSF_ASSERT(pBle->op.mstCis.checkContOpCback); + + #if(LL_ENABLE_TESTER) + pBle->chan.txPower += pBle->chan.txPwrOffset; + #endif + PalBbBleSetChannelParam(&pBle->chan); + + bbBleCb.bbParam.txCback = bbMstCisTxCompCback; + bbBleCb.bbParam.rxCback = bbMstCisRxCompCback; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; + bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION; + + PalBbBleSetDataParams(&bbBleCb.bbParam); + + bbBleCb.evtState = BB_EVT_STATE_IDLE; + + if (pCis->execCback) + { + pCis->execCback(pBod); + } +} + +/*************************************************************************************************/ +/*! + * \brief Cancel CIS master BOD. + * + * \param pBod Pointer to the BOD to cancel. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbMstCancelCisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + WSF_ASSERT(pBod && pBle); + WSF_ASSERT(pBle->op.mstCis.rxDataCback); + + PalBbBleCancelData(); + + if (bbBleCb.pRxCisDataBuf) + { + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + + /* Buffer free expected to be called during this routine. */ + pBle->op.mstCis.rxDataCback(pBod, pBuf, BB_STATUS_CANCELED); + } + + pBle->op.mstCis.cancelCback(pBod); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize for CIS master operations. + * + * Update the operation table with CIS master operations routines. + */ +/*************************************************************************************************/ +void BbBleCisMasterInit(void) +{ + bbBleRegisterOp(BB_BLE_OP_MST_CIS_EVENT, bbMstExecuteCisOp, bbMstCancelCisOp); + + memset(&bbCisStats, 0, sizeof(bbCisStats)); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_slave.c new file mode 100644 index 00000000000..5a38d7bfb63 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_cis_slave.c @@ -0,0 +1,384 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Connected isochronous stream slave baseband porting implementation file. + * + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_api.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include "wsf_trace.h" +#include + +/*! \brief Event states for scan operations. */ +enum +{ + BB_EVT_STATE_IDLE, /*!< Idle state. */ + BB_EVT_STATE_TERMINATING, /*!< BOD terminating state. */ +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +extern BbBleDataPktStats_t bbCisStats; /*!< Connection packet statistics. */ + +/*************************************************************************************************/ +/*! + * \brief Post subevent operation activities. + * + * \param pCur Current BOD. + * \param pCis Slave CIS event. + * \param status status. + */ +/*************************************************************************************************/ +static void bbSlvCisPostSubEvt(BbOpDesc_t *pCur, BbBleSlvCisEvent_t *pCis, uint8_t status) +{ + /* Calculate the next sub-event channel index. */ + pCis->postSubEvtCback(pCur, status); +} + +/*************************************************************************************************/ +/*! + * \brief Check whether to continue next operation or not. + * + * \param pCur Current BOD. + * \param pCis Slave CIS event. + * \param pNewCisCtx TRUE if switch to a new CIS context. + * + * \return TRUE if operation completed; FALSE if it continues. + */ +/*************************************************************************************************/ +static bool_t bbSlvCisCheckNextOp(BbOpDesc_t *pCur, BbBleSlvCisEvent_t *pCis, bool_t *pNewCisCtx) +{ + if (BbGetBodTerminateFlag()) + { + return TRUE; + } + + /* Update new channel index and due time. */ + uint32_t offsUsec = pCis->checkContOpCback(pCur, pNewCisCtx); + + if (offsUsec == 0) + { + /* Operation completed. */ + return TRUE; + } + + /* Update channel parameter. */ + BbBleData_t *pBle = pCur->prot.pBle; + PalBbBleSetChannelParam(&pBle->chan); + + /* Note setting radio requires setting up the channel and due time, need to be done first. */ + pCis->rxTsUsec = BbAdjustTime(pCis->rxTsUsec + offsUsec); + pCur->dueUsec = pCis->rxTsUsec; + + bbBleCb.bbParam.dueUsec = pCur->dueUsec; + bbBleCb.bbParam.rxTimeoutUsec = pCis->rxSyncDelayUsec; + + PalBbBleSetDataParams(&bbBleCb.bbParam); + + /* Update the header field and start Rx. */ + pCis->contExecCback(pCur); + + /* Operation continues. */ + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Tx completion for CIS slave operation. + * + * \param status Transmission status + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbSlvCisTxCompCback(uint8_t status) +{ + BB_ISR_START(); + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleSlvCisEvent_t * const pCis = &pCur->prot.pBle->op.slvCis; + + pCis->txDataCback(pCur, status); + + bool_t bodComplete = FALSE; + bool_t newCisCtx = FALSE; + + bodComplete = bbSlvCisCheckNextOp(pCur, pCis, &newCisCtx); + + if (status == BB_STATUS_SUCCESS) + { + if (BbGetBodTerminateFlag() || bodComplete) + { + /* Cancel TIFS timer if active. */ + PalBbBleCancelTifs(); + + /* Tx completion is end of BOD. */ + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + } + else if (status == BB_STATUS_FAILED) + { + if (bodComplete) + { + if (bbBleCb.pRxCisDataBuf != NULL) + { + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + pCis->rxDataCback(pCur, pBuf, BB_STATUS_CANCELED); + } + + /* Cancel TIFS timer if active. */ + PalBbBleCancelTifs(); + + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + } + else + { + if (bbBleCb.pRxCisDataBuf != NULL) + { + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + pCis->rxDataCback(pCur, pBuf, BB_STATUS_CANCELED); + } + + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + + /* Skip the post subevent callback if switching to the new CIS context. */ + if (newCisCtx == FALSE) + { + bbSlvCisPostSubEvt(pCur, pCis, status); + } + + /* Update statistics. */ + switch (status) + { + case BB_STATUS_SUCCESS: + BB_INC_STAT(bbCisStats.txData); + break; + case BB_STATUS_FAILED: + default: + BB_INC_STAT(bbCisStats.errData); + break; + } + + BB_ISR_MARK(bbCisStats.txIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Rx completion for CIS slave operation. + * + * \param status Reception status. + * \param rssi RSSI value. + * \param crc CRC value. + * \param timestamp Start of packet timestamp in microseconds. + * \param rxPhyOptions Rx PHY options. + * + * Setup for next action in the operation or complete the operation. + */ +/*************************************************************************************************/ +static void bbSlvCisRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_t timestamp, uint8_t rxPhyOptions) +{ + BB_ISR_START(); + + WSF_ASSERT(BbGetCurrentBod()); + + BbOpDesc_t * const pCur = BbGetCurrentBod(); + BbBleSlvCisEvent_t * const pCis = &pCur->prot.pBle->op.slvCis; + + pCis->rssi = rssi; + pCis->rxPhyOptions = rxPhyOptions; + + if (pCis->isFirstTs == TRUE) + { + /* Update startTs for the successful rx, otherwise use the due time. */ + if (status == BB_STATUS_SUCCESS) + { + pCis->startTsUsec = timestamp; + } + else + { + pCis->startTsUsec = pCur->dueUsec; + } + pCis->isFirstTs = FALSE; + pCis->rxTsUsec = pCis->startTsUsec; + } + else + { + /* Update rxTs for the successful rx, otherwise use the due time. */ + if (status == BB_STATUS_SUCCESS) + { + pCis->rxTsUsec = timestamp; + } + } + + WSF_ASSERT(bbBleCb.pRxCisDataBuf); + + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + + /* Set Tx buffer or BOD cancel expected to be called during this routine. */ + pCis->rxDataCback(pCur, pBuf, status); + + if ((status != BB_STATUS_RX_TIMEOUT) && /* BB_STATUS_RX_TIMEOUT will setup Tx which will be failed and terminate BOD. */ + BbGetBodTerminateFlag()) + { + WSF_ASSERT(!bbBleCb.pRxCisDataBuf); + + /* Cancel TIFS timer if active. */ + switch (status) + { + case BB_STATUS_SUCCESS: + PalBbBleCancelTifs(); + break; + default: + break; + } + + if (bbBleCb.evtState == BB_EVT_STATE_IDLE) + { + /* Avoid double terminating BOD */ + BbTerminateBod(); + bbBleCb.evtState = BB_EVT_STATE_TERMINATING; + } + } + + /* Update statistics. */ + switch (status) + { + case BB_STATUS_SUCCESS: + BB_INC_STAT(bbCisStats.rxData); + break; + case BB_STATUS_RX_TIMEOUT: + BB_INC_STAT(bbCisStats.rxDataTimeout); + break; + case BB_STATUS_CRC_FAILED: + BB_INC_STAT(bbCisStats.rxDataCrc); + break; + case BB_STATUS_FAILED: + default: + BB_INC_STAT(bbCisStats.errData); + break; + } + + BB_ISR_MARK(bbCisStats.rxIsrUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Execute CIS slave BOD. + * + * \param pBod Pointer to the BOD to execute. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbSlvExecuteCisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + BbBleSlvCisEvent_t * const pCis = &pBod->prot.pBle->op.slvCis; + + WSF_ASSERT(pCis->txDataCback); + WSF_ASSERT(pCis->rxDataCback); + WSF_ASSERT(pCis->execCback); + WSF_ASSERT(pCis->checkContOpCback); + + pCis->isFirstTs = TRUE; + pCis->rxTsUsec = pBod->dueUsec; + + #if(LL_ENABLE_TESTER) + pBle->chan.txPower += pBle->chan.txPwrOffset; + #endif + PalBbBleSetChannelParam(&pBle->chan); + + bbBleCb.bbParam.txCback = bbSlvCisTxCompCback; + bbBleCb.bbParam.rxCback = bbSlvCisRxCompCback; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pCis->rxTsUsec); + pCis->rxTsUsec = bbBleCb.bbParam.dueUsec; + bbBleCb.bbParam.rxTimeoutUsec = pCis->rxSyncDelayUsec; + + PalBbBleSetDataParams(&bbBleCb.bbParam); + + bbBleCb.evtState = BB_EVT_STATE_IDLE; + + pBle->op.slvCis.execCback(pBod); +} + +/*************************************************************************************************/ +/*! + * \brief Cancel CIS slave BOD. + * + * \param pBod Pointer to the BOD to cancel. + * \param pBle BLE operation parameters. + */ +/*************************************************************************************************/ +static void bbSlvCancelCisOp(BbOpDesc_t *pBod, BbBleData_t *pBle) +{ + WSF_ASSERT(pBod && pBle); + WSF_ASSERT(pBle->op.slvCis.rxDataCback); + + PalBbBleCancelData(); + + if (bbBleCb.pRxCisDataBuf) + { + uint8_t *pBuf = bbBleCb.pRxCisDataBuf; + bbBleCb.pRxCisDataBuf = NULL; + + /* Buffer free expected to be called during this routine. */ + pBle->op.slvCis.rxDataCback(pBod, pBuf, BB_STATUS_CANCELED); + } + + pBle->op.slvCis.cancelCback(pBod); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize for connected isochronous stream slave operations. + * + * Update the operation table with onnected isochronous stream slave operations routines. + */ +/*************************************************************************************************/ +void BbBleCisSlaveInit(void) +{ + bbBleRegisterOp(BB_BLE_OP_SLV_CIS_EVENT, bbSlvExecuteCisOp, bbSlvCancelCisOp); + + memset(&bbCisStats, 0, sizeof(bbCisStats)); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn.c index 8b5f509be38..e19a92d9015 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn.c @@ -1,29 +1,32 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Connectable BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Connectable BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ +#include #include "bb_api.h" #include "pal_bb.h" #include "bb_ble_int.h" +#include "bb_ble_sniffer_api.h" #if BB_DATA_PLD_MAX_LEN < LL_MAX_DATA_LEN_MIN #error "Unsupported BB_DATA_PLD_MAX_LEN value, must be greater than 27 bytes" @@ -46,8 +49,6 @@ BbBleDataPktStats_t bbConnStats; /*!< Connection packet statistics. */ * \param descs Array of transmit buffer descriptor. * \param cnt Number of descriptors. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleMstConnEvent_t::rxDataCback or \ref BbBleSlvConnEvent_t::rxDataCback * callback routine. @@ -55,10 +56,16 @@ BbBleDataPktStats_t bbConnStats; /*!< Connection packet statistics. */ /*************************************************************************************************/ void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) { +#if (BB_SNIFFER_ENABLED == TRUE) + if (bbSnifferCtx.enabled) + { + memcpy(bbSnifferCtx.txBuf, descs->pBuf, LL_DATA_HDR_MAX_LEN); + } +#endif if ((BbGetCurrentBod()->prot.pBle->chan.opType == BB_BLE_OP_MST_CONN_EVENT) && (bbBleCb.evtState == 0)) { - bbBleSetIfs(); /* master always Rx's after Tx */ + bbBleSetTifs(); /* master always Rx's after Tx */ PalBbBleTxData(descs, cnt); } else @@ -66,7 +73,7 @@ void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) BB_ISR_MARK(bbConnStats.txSetupUsec); /* TODO set only if master or if slave and Rx may follow in CE. */ - bbBleSetIfs(); + bbBleSetTifs(); PalBbBleTxTifsData(descs, cnt); } } @@ -78,8 +85,6 @@ void BbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) * \param pBuf Receive data buffer. * \param len Maximum length of data buffer. * - * \return None. - * * \note This function is expected to be called during the call context of * \ref BbBleMstConnEvent_t::rxDataCback or * \ref BbBleSlvConnEvent_t::rxDataCback callback routine. @@ -99,7 +104,7 @@ void BbBleRxData(uint8_t *pBuf, uint16_t len) if ((BbGetCurrentBod()->prot.pBle->chan.opType == BB_BLE_OP_SLV_CONN_EVENT) && (bbBleCb.evtState == 0)) { - bbBleSetIfs(); /* slave always Tx's after Rx */ + bbBleSetTifs(); /* slave always Tx's after Rx */ PalBbBleRxData(pBuf, len); } } @@ -107,8 +112,6 @@ void BbBleRxData(uint8_t *pBuf, uint16_t len) /*************************************************************************************************/ /*! * \brief Get connection packet statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetConnStats(BbBleDataPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_master.c index 4a9b2202803..2d8f2fa13a4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Connectable master BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Connectable master BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,6 +26,7 @@ #include "pal_bb.h" #include "bb_ble_int.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Global Variables @@ -38,8 +40,6 @@ extern BbBleDataPktStats_t bbConnStats; /*!< Connection packet statistics. * * * \param status Transmission status * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -52,6 +52,16 @@ static void bbMstConnTxCompCback(uint8_t status) BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleMstConnEvent_t * const pConn = &pCur->prot.pBle->op.mstConn; + +#if (BB_SNIFFER_ENABLED == TRUE) + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + WSF_ASSERT(pCur); pConn->txDataCback(pCur, status); @@ -61,7 +71,7 @@ static void bbMstConnTxCompCback(uint8_t status) { BB_ISR_MARK(bbConnStats.rxSetupUsec); - bbBleSetIfs(); /* TODO set only if Tx may follow in CE */ + bbBleSetTifs(); /* TODO set only if Tx may follow in CE */ PalBbBleRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen); } else @@ -99,6 +109,17 @@ static void bbMstConnTxCompCback(uint8_t status) break; } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.state = evtState; + pPkt->pktType.meta.status = status; + + bbBleSnifferConnPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbConnStats.txIsrUsec); } @@ -109,11 +130,9 @@ static void bbMstConnTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -126,6 +145,21 @@ static void bbMstConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleMstConnEvent_t * const pConn = &pCur->prot.pBle->op.mstConn; +#if (BB_SNIFFER_ENABLED == TRUE) + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } + + /* Copy to sniffer packet buffer before overwriting. */ + if (pPkt) + { + memcpy(pPkt->pktType.dataPkt.hdr, bbBleCb.pRxDataBuf, LL_DATA_HDR_MAX_LEN); + } +#endif + pConn->rssi = rssi; pConn->rxPhyOptions = rxPhyOptions; @@ -177,6 +211,19 @@ static void bbMstConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint break; } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.state = evtState; + pPkt->pktType.meta.status = status; + + bbBleSnifferConnPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbConnStats.rxIsrUsec); } @@ -186,12 +233,14 @@ static void bbMstConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) { +#if(LL_ENABLE_TESTER) + pBle->chan.txPower += pBle->chan.txPwrOffset; +#endif + PalBbBleSetChannelParam(&pBle->chan); WSF_ASSERT(pBle->op.mstConn.txDataCback); @@ -199,8 +248,8 @@ static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbMstConnTxCompCback; bbBleCb.bbParam.rxCback = bbMstConnRxCompCback; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; bbBleCb.bbParam.rxTimeoutUsec = 2 * LL_MAX_TIFS_DEVIATION; PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -216,8 +265,6 @@ static void bbMstExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to cancel. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbMstCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -244,8 +291,6 @@ static void bbMstCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for connectable master operations. * - * \return None. - * * Update the operation table with connectable master operations routines. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_slave.c index 19a6497e9cf..07d67c860b8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Connectable slave BLE baseband porting implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Connectable slave BLE baseband porting implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,6 +26,7 @@ #include "pal_bb.h" #include "bb_ble_int.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Global Variables @@ -38,8 +40,6 @@ extern BbBleDataPktStats_t bbConnStats; /*!< Connection packet statistics. * * * \param status Transmission status * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -52,6 +52,15 @@ static void bbSlvConnTxCompCback(uint8_t status) BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleSlvConnEvent_t * const pConn = &pCur->prot.pBle->op.slvConn; +#if (BB_SNIFFER_ENABLED == TRUE) + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } +#endif + pConn->txDataCback(pCur, status); if (status == BB_STATUS_SUCCESS) @@ -60,7 +69,7 @@ static void bbSlvConnTxCompCback(uint8_t status) { BB_ISR_MARK(bbConnStats.rxSetupUsec); - bbBleSetIfs(); /* slave always Tx's after Rx */ + bbBleSetTifs(); /* slave always Tx's after Rx */ PalBbBleRxTifsData(bbBleCb.pRxDataBuf, bbBleCb.rxDataLen); } else @@ -97,6 +106,17 @@ static void bbSlvConnTxCompCback(uint8_t status) break; } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_TX; + pPkt->pktType.meta.state = evtState; + pPkt->pktType.meta.status = status; + + bbBleSnifferConnPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbConnStats.txIsrUsec); } @@ -107,11 +127,9 @@ static void bbSlvConnTxCompCback(uint8_t status) * \param status Reception status. * \param rssi RSSI value. * \param crc CRC value. - * \param timestamp Start of packet timestamp. + * \param timestamp Start of packet timestamp in microseconds. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Setup for next action in the operation or complete the operation. */ /*************************************************************************************************/ @@ -124,6 +142,21 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleSlvConnEvent_t * const pConn = &pCur->prot.pBle->op.slvConn; +#if (BB_SNIFFER_ENABLED == TRUE) + uint8_t evtState = bbBleCb.evtState; + BbBleSnifferPkt_t * pPkt = NULL; + if (bbSnifferCtx.enabled) + { + pPkt = bbSnifferCtx.snifferGetPktFn(); + } + + /* Copy to sniffer packet buffer before overwriting. */ + if (pPkt) + { + memcpy(pPkt->pktType.dataPkt.hdr, bbBleCb.pRxDataBuf, LL_DATA_HDR_MAX_LEN); + } +#endif + pConn->rssi = rssi; pConn->rxPhyOptions = rxPhyOptions; @@ -131,7 +164,7 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint { bbBleCb.evtState = 1; - pConn->startTs = timestamp; + pConn->startTsUsec = timestamp; } WSF_ASSERT(bbBleCb.pRxDataBuf); @@ -178,6 +211,19 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint break; } +#if (BB_SNIFFER_ENABLED == TRUE) + if (pPkt) + { + pPkt->pktType.meta.type = BB_SNIFF_PKT_TYPE_RX; + pPkt->pktType.meta.rssi = rssi; + pPkt->pktType.meta.timeStamp = timestamp; + pPkt->pktType.meta.state = evtState; + pPkt->pktType.meta.status = status; + + bbBleSnifferConnPktHandler(pCur, pPkt); + } +#endif + BB_ISR_MARK(bbConnStats.rxIsrUsec); } @@ -187,8 +233,6 @@ static void bbSlvConnRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -198,12 +242,16 @@ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) WSF_ASSERT(pConn->txDataCback); WSF_ASSERT(pConn->rxDataCback); +#if(LL_ENABLE_TESTER) + pBle->chan.txPower += pBle->chan.txPwrOffset; +#endif + PalBbBleSetChannelParam(&pBle->chan); bbBleCb.bbParam.txCback = bbSlvConnTxCompCback; bbBleCb.bbParam.rxCback = bbSlvConnRxCompCback; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; bbBleCb.bbParam.rxTimeoutUsec = pConn->rxSyncDelayUsec; PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -219,8 +267,6 @@ static void bbSlvExecuteConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to cancel. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -247,8 +293,6 @@ static void bbSlvCancelConnOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for connectable slave operations. * - * \return None. - * * Update the operation table with connectable slave operations routines. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_test.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_dtm.c similarity index 80% rename from features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_test.c rename to features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_dtm.c index bf2f8f2a2bf..31aa43f3bff 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_test.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_dtm.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Generic BLE baseband driver implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Generic BLE baseband driver implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -39,8 +40,6 @@ extern BbRtCfg_t *pBbRtCfg; * * \param status Completion status. * - * \return None. - * * Completion handler for the BLE transmit test operation. */ /*************************************************************************************************/ @@ -57,6 +56,9 @@ static void bbTestTxCompCback(uint8_t status) switch (status) { case BB_STATUS_SUCCESS: + PalBbBleCancelTifs(); + + /* Terminate BOD if new channel parameters are required. */ bodComplete = !pTx->testCback(pCur, status); break; @@ -73,14 +75,9 @@ static void bbTestTxCompCback(uint8_t status) } else { - const uint32_t pktInterUsec = pTx->pktInterUsec + bbBleCb.bbParam.dueOffsetUsec; - const uint32_t pktInter = BB_US_TO_BB_TICKS(pktInterUsec); - int16_t dueOffsetUsec = pktInterUsec - BB_TICKS_TO_US(pktInter); + const uint32_t pktInterUsec = pTx->pktInterUsec; - PalBbBleCancelTifs(); - - bbBleCb.bbParam.due = bbBleCb.bbParam.due + pktInter; - bbBleCb.bbParam.dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + bbBleCb.bbParam.dueUsec = BbAdjustTime(bbBleCb.bbParam.dueUsec + pktInterUsec); PalBbBleSetChannelParam(&pBle->chan); PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -111,8 +108,6 @@ static void bbTestTxCompCback(uint8_t status) * \param timestamp Start of packet timestamp. * \param rxPhyOptions Rx PHY options. * - * \return None. - * * Completion handler for the BLE receive test operation. */ /*************************************************************************************************/ @@ -150,11 +145,8 @@ static void bbTestRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_ PalBbBleCancelTifs(); const uint32_t pktInterUsec = pBbRtCfg->rfSetupDelayUs; - const uint32_t pktInter = BB_US_TO_BB_TICKS(pktInterUsec); - int16_t dueOffsetUsec = pktInterUsec - BB_TICKS_TO_US(pktInter); - bbBleCb.bbParam.due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + pktInter; - bbBleCb.bbParam.dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + bbBleCb.bbParam.dueUsec = BbAdjustTime(PalBbGetCurrentTime() + pktInterUsec); bbBleCb.bbParam.rxTimeoutUsec = pRx->rxSyncDelayUsec; PalBbBleSetChannelParam(&pBle->chan); PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -187,8 +179,6 @@ static void bbTestRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_ * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbTestCleanupOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -203,8 +193,6 @@ static void bbTestCleanupOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecuteTestTxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -213,8 +201,8 @@ static void bbSlvExecuteTestTxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbTestTxCompCback; bbBleCb.bbParam.rxCback = bbTestRxCompCback; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; PalBbBleSetChannelParam(&pBle->chan); PalBbBleSetDataParams(&bbBleCb.bbParam); @@ -230,8 +218,6 @@ static void bbSlvExecuteTestTxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) * * \param pBod Pointer to the BOD to execute. * \param pBle BLE operation parameters. - * - * \return None. */ /*************************************************************************************************/ static void bbSlvExecuteTestRxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) @@ -240,8 +226,8 @@ static void bbSlvExecuteTestRxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) bbBleCb.bbParam.txCback = bbTestTxCompCback; bbBleCb.bbParam.rxCback = bbTestRxCompCback; - bbBleCb.bbParam.due = pBod->due; - bbBleCb.bbParam.dueOffsetUsec = pBod->dueOffsetUsec; + bbBleCb.bbParam.dueUsec = BbAdjustTime(pBod->dueUsec); + pBod->dueUsec = bbBleCb.bbParam.dueUsec; bbBleCb.bbParam.rxTimeoutUsec = pRx->rxSyncDelayUsec; PalBbBleSetChannelParam(&pBle->chan); @@ -255,8 +241,6 @@ static void bbSlvExecuteTestRxOp(BbOpDesc_t *pBod, BbBleData_t *pBle) /*! * \brief Initialize for direct test mode operations. * - * \return None. - * * Update the operation table with direct test mode operations routines. */ /*************************************************************************************************/ @@ -271,8 +255,6 @@ void BbBleTestInit(void) /*************************************************************************************************/ /*! * \brief Get test mode packet statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetTestStats(BbBleDataPktStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_int.h index d37c770c6ac..d9ded94f9cf 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_int.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_int.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal BLE baseband interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal BLE baseband interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -45,10 +46,28 @@ extern "C" { #define BB_ADVB_MAX_LEN WSF_MAX(BB_FIXED_ADVB_PKT_LEN, LL_ADVB_MAX_LEN) /*! \brief Mark the start of an ISR. */ -#define BB_ISR_START() bbIsrStartTime = PalBbGetCurrentTime(USE_RTC_BB_CLK) +#define BB_ISR_START() bbIsrStartTime = PalBbGetCurrentTime() /*! \brief Mark the ISR duration, recording the high watermark. */ -#define BB_ISR_MARK(x) x = WSF_MAX(x, BB_TICKS_TO_US(PalBbGetCurrentTime(USE_RTC_BB_CLK) - bbIsrStartTime)) +#define BB_ISR_MARK(x) x = WSF_MAX(x, PalBbGetCurrentTime() - bbIsrStartTime) + +/*! \brief Event states for advertising operations. */ +enum +{ + BB_EVT_STATE_TX_ADV_IND, /*!< Advertising indication. */ + BB_EVT_STATE_RX_SCAN_OR_CONN_INIT, /*!< Scan or connection init packet. */ + BB_EVT_STATE_TX_SCAN_OR_CONN_RSP, /*!< Scan or connection response. */ + BB_EVT_STATE_TX_CHAIN_IND /*!< Chain indication. */ +}; + +/*! \brief Event states for scanning operations. */ +enum +{ + BB_EVT_STATE_RX_ADV_IND, /*!< Advertising indication. */ + BB_EVT_STATE_TX_SCAN_OR_CONN_INIT, /*!< Scan or connection init packet. */ + BB_EVT_STATE_RX_SCAN_OR_CONN_RSP, /*!< Scan or connection response. */ + BB_EVT_STATE_RX_CHAIN_IND /*!< Chain indication. */ +}; /************************************************************************************************** Data Types @@ -69,13 +88,14 @@ typedef struct uint8_t evtState; /*!< Action state of the currently operating BOD. */ uint8_t advChIdx; /*!< Current advertising channel index. */ uint8_t numChUsed; /*!< Total number of channels visited. */ - uint32_t lastScanStart; /*!< Last scan start time. */ + uint32_t lastScanStartUsec; /*!< Last scan start time in microseconds. */ PalBbBleDataParam_t bbParam; /*!< Baseband data parameters. */ uint16_t rxDataLen; /*!< Receive data buffer length. */ uint8_t *pRxDataBuf; /*!< Current Rx data buffer. */ + /* TODO combine with above? */ uint16_t rxCisDataLen; /*!< Receive CIS data buffer length. */ uint8_t *pRxCisDataBuf; /*!< Current Rx CIS data buffer. */ } bbBleCtrlBlk_t; @@ -97,8 +117,6 @@ extern uint32_t bbIsrStartTime; * \param opType Operation type. * \param execOpCback Execute operation callback. * \param cancelOpCback Cancel operation callback. - * - * \return None. */ /*************************************************************************************************/ void bbBleRegisterOp(uint8_t opType, bbBleExecOpFn_t execOpCback, bbBleExecOpFn_t cancelOpCback); @@ -111,29 +129,42 @@ void bbBleRegisterOp(uint8_t opType, bbBleExecOpFn_t execOpCback, bbBleExecOpFn_ /*! * \brief Clear IFS in operation. * - * \return None. - * * The BB may choose not to enable IFS after the next Tx or Rx. */ /*************************************************************************************************/ static inline void bbBleClrIfs(void) { - PalBbBleOpParam_t opParams = { .ifsSetup = FALSE, .ifsUsec = 0 }; + /* PalBbBleOpParam_t opParams = { .ifsMode = PAL_BB_IFS_MODE_CLR, .ifsTime = 0, .pIfsChan = NULL }; */ + PalBbBleOpParam_t opParams = { 0 }; + PalBbBleSetOpParams(&opParams); +} + +/*************************************************************************************************/ +/*! + * \brief Set TIFS in operation. + * + * The BB must enable TIFS after the next Tx or Rx. + */ +/*************************************************************************************************/ +static inline void bbBleSetTifs(void) +{ + PalBbBleOpParam_t opParams = { .ifsMode = PAL_BB_IFS_MODE_TOGGLE_TIFS, .ifsTime = 0, .pIfsChan = NULL }; PalBbBleSetOpParams(&opParams); } /*************************************************************************************************/ /*! - * \brief Set IFS in operation. + * \brief Set absolute time IFS in operation. * - * \return None. + * \param ifsTime Due time of the next PDU. + * \param pIfsChan Channel of the next PDU. * - * The BB must enable IFS after the next Tx or Rx. + * The BB must enable IFS with absolute time after the next Tx or Rx. */ /*************************************************************************************************/ -static inline void bbBleSetIfs(void) +static inline void bbBleSetAbsIfs(uint32_t ifsTime, PalBbBleChan_t *pIfsChan) { - PalBbBleOpParam_t opParams = { .ifsSetup = TRUE, .ifsUsec = LL_BLE_TIFS_US }; + PalBbBleOpParam_t opParams = { .ifsMode = PAL_BB_IFS_MODE_SAME_ABS, .ifsTime = ifsTime, .pIfsChan = pIfsChan }; PalBbBleSetOpParams(&opParams); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_main.c index 88029616766..733b15fe423 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Generic BLE baseband driver implementation file. + * \file + * + * \brief Generic BLE baseband driver implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -39,8 +40,6 @@ bbBleCtrlBlk_t bbBleCb; /*!< BB BLE control block. */ /*************************************************************************************************/ /*! * \brief Start BB processing of BLE protocol. - * - * \return None. */ /*************************************************************************************************/ static void bbBleStartBle(void) @@ -52,8 +51,6 @@ static void bbBleStartBle(void) /*************************************************************************************************/ /*! * \brief Start BB processing of BLE protocol. - * - * \return None. */ /*************************************************************************************************/ static void bbBleStopBle(void) @@ -64,8 +61,6 @@ static void bbBleStopBle(void) /*************************************************************************************************/ /*! * \brief Start BB processing of BLE DTM protocol. - * - * \return None. */ /*************************************************************************************************/ static void bbBleStartBleDtm(void) @@ -77,8 +72,6 @@ static void bbBleStartBleDtm(void) /*************************************************************************************************/ /*! * \brief Start BB processing of PRBS15 protocol. - * - * \return None. */ /*************************************************************************************************/ static void bbBleStartPrbs15(void) @@ -91,8 +84,6 @@ static void bbBleStartPrbs15(void) /*************************************************************************************************/ /*! * \brief Start BB processing of PRBS15 protocol. - * - * \return None. */ /*************************************************************************************************/ static void bbBleStopPrbs15(void) @@ -106,8 +97,6 @@ static void bbBleStopPrbs15(void) * \brief Execute operation. * * \param pBod Pointer to the BOD to execute. - * - * \return None. */ /*************************************************************************************************/ static void bbBleExecOp(BbOpDesc_t *pBod) @@ -127,8 +116,6 @@ static void bbBleExecOp(BbOpDesc_t *pBod) * \brief Cancel operation. * * \param pBod Pointer to the BOD to cancel. - * - * \return None. */ /*************************************************************************************************/ static void bbBleCancelOp(BbOpDesc_t *pBod) @@ -142,11 +129,21 @@ static void bbBleCancelOp(BbOpDesc_t *pBod) bbBleCb.opCbacks[pBle->chan.opType].cancelOpCback(pBod, pBle); } } + /*************************************************************************************************/ /*! - * \brief Initialize the BLE BB. + * \brief Low power operation. * - * \return None. + */ +/*************************************************************************************************/ +static void bbBleLowPower(void) +{ + PalBbBleLowPower(); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize the BLE BB. * * Initialize baseband resources. */ @@ -157,6 +154,7 @@ void BbBleInit(void) BbRegisterProt(BB_PROT_BLE, bbBleExecOp, bbBleCancelOp, bbBleStartBle, bbBleStopBle); BbRegisterProt(BB_PROT_BLE_DTM, bbBleExecOp, bbBleCancelOp, bbBleStartBleDtm, bbBleStopBle); BbRegisterProt(BB_PROT_PRBS15, NULL, bbBleCancelOp, bbBleStartPrbs15, bbBleStopPrbs15); + BbRegisterProtLowPower(BB_PROT_BLE, bbBleLowPower); memset(&bbBleCb, 0, sizeof(bbBleCb)); } @@ -168,8 +166,6 @@ void BbBleInit(void) * \param opType Operation type. * \param execOpCback Execute operation callback. * \param cancelOpCback Cancel operation callback. - * - * \return None. */ /*************************************************************************************************/ void bbBleRegisterOp(uint8_t opType, bbBleExecOpFn_t execOpCback, bbBleExecOpFn_t cancelOpCback) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_pdufilt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_pdufilt.c index 1638e68a7f1..d52f9e7c8e1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_pdufilt.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_pdufilt.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Generic BLE device filtering implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Generic BLE device filtering implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -154,6 +155,37 @@ static inline uint8_t bbBlePduFiltResolvePeer(bool_t peerAddrResEna, bool_t forc } } } + else if (!(*pPeerAddrRand && BDA64_ADDR_IS_RPA(*pPeerAddr))) + { + /* Even if address resolution is disabled, filter PDU if network privacy is enabled. */ + switch (BbBleResListPeerStatus(*pPeerAddrRand, *pPeerAddr)) + { + /*** other than RPA that cannot have RPA ***/ + + case BB_BLE_RESLIST_STATUS_ZERO_IRK: + case BB_BLE_RESLIST_STATUS_ID_ADDR_NOT_IN_LIST: + default: + return BB_BLE_PDU_FILT_OK; + + /*** other than RPA that can have RPA ***/ + + case BB_BLE_RESLIST_STATUS_RES_ADDR_ASSIGNED: + case BB_BLE_RESLIST_STATUS_RES_ADDR_UNASSIGNED: + { + uint8_t privMode; + + /* Refuse to accept peer identity address. */ + if (!BbBleResListGetPrivacyMode(*pPeerAddrRand, *pPeerAddr, &privMode) || + (privMode == BB_BLE_RESLIST_PRIV_MODE_NETWORK)) + { + BB_INC_PDUFILT_STAT(failPeerPrivAddrReq); + return BB_BLE_PDU_FILT_NOT_OK; + } + + return BB_BLE_PDU_FILT_OK; + } + } + } /* Address will be accepted based upon match. */ return BB_BLE_PDU_FILT_OK; @@ -172,8 +204,8 @@ static inline uint8_t bbBlePduFiltResolvePeer(bool_t peerAddrResEna, bool_t forc * \return Tri-state result (OK, NOT_OK, UNKNOWN). */ /*************************************************************************************************/ -static inline bool_t bbBlePduFiltMatchPeer(bool_t addrMatchEna, bool_t idAddrRand, uint64_t idAddr, - bool_t addrMatchRand, uint64_t addrMatch) +static inline uint8_t bbBlePduFiltMatchPeer(bool_t addrMatchEna, bool_t idAddrRand, uint64_t idAddr, + bool_t addrMatchRand, uint64_t addrMatch) { if (addrMatchEna) { @@ -202,8 +234,8 @@ static inline bool_t bbBlePduFiltMatchPeer(bool_t addrMatchEna, bool_t idAddrRan * \return Tri-state result (OK, NOT_OK, UNKNOWN). */ /*************************************************************************************************/ -static inline bool_t bbBlePduFiltWhiteList(bool_t peerWhiteListEna, bool_t peerIdAddrRand, - uint64_t peerIdAddr) +static inline uint8_t bbBlePduFiltWhiteList(bool_t peerWhiteListEna, bool_t peerIdAddrRand, + uint64_t peerIdAddr) { if (peerWhiteListEna) { @@ -311,8 +343,8 @@ static inline uint8_t bbBlePduFiltResolveLocal(bool_t localAddrResEna, bool_t fo * \return Tri-state result (OK, NOT_OK, UNKNOWN). */ /*************************************************************************************************/ -static inline bool_t bbBlePduFiltMatchLocal(bool_t addrMatchEna, bool_t idAddrRand, uint64_t idAddr, - bool_t addrMatchRand, uint64_t addrMatch) +static inline uint8_t bbBlePduFiltMatchLocal(bool_t addrMatchEna, bool_t idAddrRand, uint64_t idAddr, + bool_t addrMatchRand, uint64_t addrMatch) { if (addrMatchEna) { @@ -389,7 +421,7 @@ bool_t BbBlePduFiltCheck(const uint8_t *pBuf, const bbBlePduFiltParams_t *pFiltP /* Resolve peer address to pass through filters. */ switch (bbBlePduFiltResolvePeer(BB_BLE_PDU_FILT_FLAG_IS_SET(pFiltParams, PEER_ADDR_RES_ENA), forceRes, - &pFiltResults->peerIdAddrRand, + (uint8_t *)&pFiltResults->peerIdAddrRand, &pFiltResults->peerIdAddr)) { case BB_BLE_PDU_FILT_OK: @@ -549,6 +581,7 @@ bool_t BbBleExtPduFiltCheck(const bbBlePduExtFiltParams_t *pExtFiltParams, #endif /*** Filter PDU by PDU type. ***/ + if ((pFiltParams->pduTypeFilt & (1 << pExtFiltParams->pduType)) == 0) { BB_INC_PDUFILT_STAT(failPduTypeFilt); @@ -566,7 +599,7 @@ bool_t BbBleExtPduFiltCheck(const bbBlePduExtFiltParams_t *pExtFiltParams, /* Resolve peer address to pass through filters. */ switch (bbBlePduFiltResolvePeer(BB_BLE_PDU_FILT_FLAG_IS_SET(pFiltParams, PEER_ADDR_RES_ENA), forceRes, - &pFiltResults->peerIdAddrRand, + (uint8_t *)&pFiltResults->peerIdAddrRand, &pFiltResults->peerIdAddr)) { case BB_BLE_PDU_FILT_OK: @@ -695,8 +728,6 @@ bool_t BbBleExtPduFiltCheck(const bbBlePduExtFiltParams_t *pExtFiltParams, * \brief Get PDU filter statistics. * * \param pStats PDU filter statistics. - * - * \return None. */ /*************************************************************************************************/ void BbBleGetPduFiltStats(BbBlePduFiltStats_t *pStats) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_periodiclist.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_periodiclist.c index e1684340d13..e821ec924f4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_periodiclist.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_periodiclist.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Generic BLE whitelist implementation file. + * \file + * + * \brief Generic BLE whitelist implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -102,7 +103,7 @@ uint16_t BbBleInitPeriodicList(uint8_t numEntries, uint8_t *pFreeMem, uint32_t f /*************************************************************************************************/ bool_t BbBlePeriodicListCheckAddr(uint8_t addrType, uint64_t addr, uint8_t SID) { - for (uint8_t i = 0; i < bbBlePeriodicListNumEntries; i++) + for (unsigned int i = 0; i < bbBlePeriodicListNumEntries; i++) { if ((pBbBlePeriodicListFilt[i].addrType == addrType) && (pBbBlePeriodicListFilt[i].addr == addr) && @@ -135,8 +136,6 @@ uint8_t BbBlePeriodicListGetSize(void) /*! * \brief Clear all periodic list entries. * - * \return None. - * * Clear all periodic list entries stored in the BB. * * \note No resource synchronization is required to modify the periodic list resource as diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_reslist.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_reslist.c index 4da6eb99c4d..66b2f4516f8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_reslist.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_reslist.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Generic BLE resolving list implementation file. + * \file + * + * \brief Generic BLE resolving list implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,8 +26,8 @@ #include "bb_ble_api.h" #include "bb_ble_api_reslist.h" #include "bb_ble_api_pdufilt.h" -#include "stack/platform/include/pal_bb_ble.h" -#include "stack/platform/include/pal_crypto.h" +#include "pal_bb_ble.h" +#include "pal_crypto.h" #include "wsf_assert.h" #include "ll_math.h" #include "util/bda.h" @@ -125,8 +126,6 @@ uint16_t BbBleInitResolvingList(uint8_t numEntries, uint8_t *pFreeMem, uint32_t * \brief Set address resolution needed callback. * * \param cback Callback. - * - * \return None. */ /*************************************************************************************************/ void BbBleResListSetAddrResNeededCback(bbBleResListAddrResNeeded_t cback) @@ -263,8 +262,6 @@ uint8_t BbBleResListGetSize(void) /*! * \brief Clear resolving list. * - * \return None. - * * Clear all resolving list entries stored in the BB. */ /*************************************************************************************************/ @@ -788,7 +785,7 @@ bool_t BbBleResListResolveLocal(uint64_t rpa, uint8_t *pPeerAddrType, uint64_t * * Get the peer resolvable private address status */ /*************************************************************************************************/ -bool_t BbBleResListPeerStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) +uint8_t BbBleResListPeerStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) { bbBleResListEntry_t *pEntry; @@ -824,7 +821,7 @@ bool_t BbBleResListPeerStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) * Get the peer resolvable private address status */ /*************************************************************************************************/ -bool_t BbBleResListLocalStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) +uint8_t BbBleResListLocalStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) { bbBleResListEntry_t *pEntry; @@ -852,8 +849,6 @@ bool_t BbBleResListLocalStatus(bool_t peerAddrRand, uint64_t peerIdentityAddr) /*! * \brief Handle timeout of local resolvable addresses. * - * \return None. - * * A new local resolvable address will be generated for each entry in the resolving list. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_sniffer.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_sniffer.c new file mode 100644 index 00000000000..f69df88d1cd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_sniffer.c @@ -0,0 +1,397 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief BB BLE Sniffer utility function definition file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_ble_sniffer_api.h" +#include "wsf_types.h" +#include "pal_bb_ble.h" +#include "bb_api.h" +#include "ll_api.h" +#include "bb_ble_api_op.h" +#include "wsf_trace.h" +#include "wsf_assert.h" +#include "pal_bb.h" +#include "bb_ble_int.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! brief Sniffer VS output packet function placeholder. */ +static void bbSnifferOutputVendorSpec(BbBleSnifferPkt_t * pPktData); + +/*! brief Sniffer output table. */ +bbSnifferFn_t bbSnifferOutTbl[BB_SNIFFER_OUTPUT_TOTAL_METHODS] = +{ + bbSnifferOutputVendorSpec /* BB_SNIFFER_OUTPUT_HCI_TOKEN */ +}; + +/*! brief Sniffer VS get packet function placeholder. */ +static BbBleSnifferPkt_t * bbSnifferGetPktVendorSpec(); + +/*! brief Sniffer get packet table. */ +bbSnifferGetPktFn_t bbSnifferGetPktTbl[BB_SNIFFER_OUTPUT_TOTAL_METHODS] = +{ + bbSnifferGetPktVendorSpec /* BB_SNIFFER_OUTPUT_HCI_TOKEN */ +}; +/*! brief Sniffer context. */ +bbSnifferCtx_t bbSnifferCtx; + +/************************************************************************************************** + Packet retrival methods +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Retrive packet for processing. + * + * \return Pointer to packet to be packed. + * + */ +/*************************************************************************************************/ +static BbBleSnifferPkt_t * bbSnifferGetPktVendorSpec() +{ + BbBleSnifferHciCtx_t * pHci = &bbSnifferCtx.outputCtx.hci; + + if ((pHci->bufIdx == BB_SNIFFER_MAX_NUM_BUF) || + (bbSnifferCtx.enabled == FALSE)) + { + return NULL; + } + + return &pHci->pktBuf[pHci->bufIdx]; +} + + +/************************************************************************************************** + Output methods +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Finalize sniffer packet by incrementing index. + * + * \param pPktData Packet to be pushed. + * + */ +/*************************************************************************************************/ +static void bbSnifferOutputVendorSpec(BbBleSnifferPkt_t * pPktData) +{ + BbBleSnifferHciCtx_t * pHci = &bbSnifferCtx.outputCtx.hci; + + pHci->bufIdx++; +} +/*************************************************************************************************/ +/*! + * \brief Master primary scan sniffer packet handler. + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferMstScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData) +{ + BbBleMstAdvEvent_t * pScan = &pBod->prot.pBle->op.mstAdv; + + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack header. */ + switch (pPktData->pktType.meta.state) + { + case BB_EVT_STATE_RX_ADV_IND: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_TX_SCAN_OR_CONN_INIT: + memcpy(pPktData->pktType.advPkt.hdr, pScan->pTxReqBuf, LL_ADV_HDR_LEN); + break; + + case BB_EVT_STATE_RX_SCAN_OR_CONN_RSP: + /* Handled in the Rx Callback. */ + break; + + default: + break; + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Master auxiliary scan sniffer packet handler + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferMstAuxScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t *pPktData) +{ + BbBleMstAuxAdvEvent_t * pScan = &pBod->prot.pBle->op.mstAuxAdv; + + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack header. */ + switch (pPktData->pktType.meta.state) + { + case BB_EVT_STATE_RX_ADV_IND: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_TX_SCAN_OR_CONN_INIT: + memcpy(pPktData->pktType.advPkt.hdr, pScan->pTxAuxReqBuf, LL_ADV_HDR_LEN); + break; + + case BB_EVT_STATE_RX_SCAN_OR_CONN_RSP: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_RX_CHAIN_IND: + /* Handled in the Rx callback. */ + break; + + default: + break; + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Master periodic scan sniffer packet handler. + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferMstPerScanPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t *pPktData) +{ + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack header. */ + switch (pPktData->pktType.meta.state) + { + case BB_EVT_STATE_RX_ADV_IND: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_RX_CHAIN_IND: + /* Handled in the Rx callback. */ + break; + + default: + break; + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Slave primary advertising sniffer packet handler. + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferSlvAdvPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData) +{ + BbBleSlvAdvEvent_t * pAdv = &pBod->prot.pBle->op.slvAdv; + + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack saved channel index. */ + pPktData->pktType.meta.chan.chanIdx = bbSnifferCtx.chanIdx; + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack header. */ + switch (pPktData->pktType.meta.state) + { + case BB_EVT_STATE_TX_ADV_IND: + memcpy(pPktData->pktType.advPkt.hdr, pAdv->pTxAdvBuf, LL_ADV_HDR_LEN); + break; + + case BB_EVT_STATE_RX_SCAN_OR_CONN_INIT: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_TX_SCAN_OR_CONN_RSP: + memcpy(pPktData->pktType.advPkt.hdr, pAdv->pTxRspBuf, LL_ADV_HDR_LEN); + break; + + default: + break; + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Slave auxiliary advertising sniffer packet handler. + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferSlvAuxAdvPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData) +{ + BbBleSlvAuxAdvEvent_t * pAdv = &pBod->prot.pBle->op.slvAuxAdv; + + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack header. */ + switch (pPktData->pktType.meta.state) + { + case BB_EVT_STATE_TX_ADV_IND: + /* Handled in the Tx Callback. */ + break; + + case BB_EVT_STATE_RX_SCAN_OR_CONN_INIT: + /* Handled in the Rx Callback. */ + break; + + case BB_EVT_STATE_TX_SCAN_OR_CONN_RSP: + memcpy(pPktData->pktType.advPkt.hdr, pAdv->txAuxRspPdu[0].pBuf, LL_ADV_HDR_LEN); + break; + + case BB_EVT_STATE_TX_CHAIN_IND: + /* Handled in the Tx Callback. */ + break; + + default: + break; + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Connection sniffer packet handler. + * + * \param pBod Pointer to BOD. + * \param pPktData Pointer to sniffer packet. + * + * Pack sniffer packet and call to output method function. + */ +/*************************************************************************************************/ +void bbBleSnifferConnPktHandler(BbOpDesc_t * pBod, BbBleSnifferPkt_t * pPktData) +{ + /* BbBleMstConnEvent_t * pConn = &pBod->prot.pBle->op.mstConn; */ + + /* Pack channelization data. */ + memcpy(&pPktData->pktType.meta.chan, &pBod->prot.pBle->chan, sizeof(pPktData->pktType.meta.chan)); + + /* Pack metadata. */ + pPktData->pktType.meta.timeStamp = bbSnifferCtx.packetCtr++; + + /* Pack Header. */ + if (pPktData->pktType.meta.type == BB_SNIFF_PKT_TYPE_TX) + { + memcpy(pPktData->pktType.dataPkt.hdr, bbSnifferCtx.txBuf, LL_DATA_HDR_MAX_LEN); + } + else /* (type == BB_SNIFF_PKT_TYPE_RX) */ + { + /* Header copy is done in the Rx comp callback. */ + } + + WSF_ASSERT(bbSnifferCtx.snifferOutCb); + + bbSnifferCtx.snifferOutCb(pPktData); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize packet sniffer + * + * \param outMethod Output method. + * \param enable Enable. + * + * \return Status error code. + * + * Initialize packet sniffer with specified output method. + */ +/*************************************************************************************************/ +uint8_t BbBleInitSniffer(uint8_t outMethod, bool_t enable) +{ + memset(&bbSnifferCtx, 0, sizeof(bbSnifferCtx)); + + if (enable == FALSE) + { + return LL_SUCCESS; + } + + if (outMethod >= BB_SNIFFER_OUTPUT_TOTAL_METHODS) + { + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + bbSnifferCtx.snifferGetPktFn = bbSnifferGetPktTbl[outMethod]; + bbSnifferCtx.snifferOutCb = bbSnifferOutTbl[outMethod]; + bbSnifferCtx.enabled = enable; + + return LL_SUCCESS; +} + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_whitelist.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_whitelist.c index dd55b28fbd4..7be8a5c68ad 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_whitelist.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/bb/bb_ble_whitelist.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Generic BLE whitelist implementation file. + * \file + * + * \brief Generic BLE whitelist implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -135,8 +136,6 @@ uint8_t BbBleWhiteListGetSize(void) /*! * \brief Clear all white list entries. * - * \return None. - * * Clear all white list entries stored in the BB. * * \note No resource synchronization is required to modify the white list resource as @@ -226,8 +225,6 @@ bool_t BbBleWhiteListRemove(bool_t randAddr, uint64_t addr) /*************************************************************************************************/ /*! * \brief Add anonymous device to the white list. - * - * \return None. */ /*************************************************************************************************/ void BbBleWhiteListAddAnonymous(void) @@ -238,8 +235,6 @@ void BbBleWhiteListAddAnonymous(void) /*************************************************************************************************/ /*! * \brief Remove anonymous device from the white list. - * - * \return None. */ /*************************************************************************************************/ void BbBleWhiteListRemoveAnonymous(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api.h index b34d9f7cf0c..2f7e97d61db 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller common interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller common interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -59,7 +60,9 @@ enum LCTR_DISP_TRANFER_SYNC, /*!< Periodic Sync Transfer message dispatch handler type. */ LCTR_DISP_PER_SCAN, /*!< Periodic Scanning message dispatch handler type. */ LCTR_DISP_ACAD, /*!< ACAD message dispatch handler type (currently only used by slave). */ - LCTR_DISP_CIS, /*!< Connected isochronous stream dispatch handler type. */ + LCTR_DISP_CIS, /*!< Connected Isochronous Stream dispatch handler type. */ + LCTR_DISP_BIG_BCST, /*!< Broadcast Isochronous Group broadcasting message dispatch handler type. */ + LCTR_DISP_BIG_SYNC, /*!< Broadcast Isochronous Group synchronization message dispatch handler type. */ LCTR_DISP_TOTAL, /*!< Total number of dispatch handlers. */ /* Special IDs */ LCTR_DISP_FIRST_SM = LCTR_DISP_CONN_IND+1, /*!< First state machine. */ @@ -81,7 +84,7 @@ enum LCTR_EVENT_TX_COMPLETE, /*!< Transmit data PDU completed. */ LCTR_EVENT_CIS_TX_PENDING, /*!< Transmit data PDU pending. */ LCTR_EVENT_CIS_RX_PENDING, /*!< Receive data PDU pending. */ - LCTR_EVENT_CIS_TX_COMPLETE, /*!< Transmit data PDU completed. */ + LCTR_EVENT_ISO_TX_COMPLETE, /*!< Transmit ISO SDU completed. */ LCTR_EVENT_RX_ADVB, /*!< Receive AdvB PDU completed. */ LCTR_EVENT_RX_DIRECT_ADVB, /*!< Receive direct AdvB PDU completed. */ LCTR_EVENT_RX_SCAN_REQ, /*!< Receive scan request PDU completed. */ @@ -107,7 +110,7 @@ typedef struct { uint16_t handle; /*!< Handle. */ uint8_t dispId; /*!< Dispatch ID. */ - uint8_t event; /*!< PDU ID. */ + uint8_t event; /*!< Event ID. */ } lctrMsgHdr_t; /*! \brief Channel map update message. */ @@ -117,6 +120,13 @@ typedef struct uint64_t chanMap; /*!< Channel map. */ } lctrChanMapUpdate_t; +/*! \brief BIG created message. */ +typedef struct +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + uint8_t bigHandle; /*!< BIG handle. */ +} lctrBigCreated_t; + /*! \brief Connect request PDU. */ typedef struct { @@ -140,7 +150,7 @@ typedef struct { lctrMsgHdr_t hdr; /*!< Message header. */ lctrConnInd_t connInd; /*!< Connection indication. */ - uint32_t connIndEndTs; /*!< Connection indication packet end timestamp. */ + uint32_t connIndEndTsUsec; /*!< Connection indication packet end timestamp in microseconds. */ uint8_t peerIdAddrType; /*!< Peer identity address type. */ uint8_t usedChSel; /*!< Used channel selection. */ uint8_t phy; /*!< PHY selection. */ @@ -156,22 +166,34 @@ typedef struct Global Variables **************************************************************************************************/ -/* \brief Call signature for periodic enabled check function */ +/*! \brief Call signature for periodic enabled check function */ typedef bool_t (*LctrIsPerAdvEnabledFn_t)(uint8_t handle); -/* Function pointer for periodic advertising enable check */ +/*! \brief Function pointer for periodic advertising enable check */ extern LctrIsPerAdvEnabledFn_t LctrPerAdvEnabled; -/* \brief Call signature for extended scan enabled check function. */ +/*! \brief Call signature to update CIS channel map */ +typedef void (*LctrUpdateCisChanMapFn_t)(uint16_t aclHandle); + +/*! \brief Function pointer to update CIS channel map */ +extern LctrUpdateCisChanMapFn_t LctrUpdateCisChanMapFn; + +/*! \brief Call signature for extended scan enabled check function. */ typedef bool_t (*LctrExtCheckFn_t)(uint8_t scanPhy); -/* Function pointer for extended scan enable check. */ +/*! \brief Function pointer for extended scan enable check. */ extern LctrExtCheckFn_t LctrMstExtScanEnabled; -/* Function pointer for extended advertising init enable check. */ +/*! \brief Function pointer for extended advertising init enable check. */ extern LctrExtCheckFn_t LctrMstExtInitEnabled; -/* Runtime configuration. */ +/*! \brief Call signature for periodic sync pending check. */ +typedef bool_t (*LctrPerSyncPendFn_t)(void); + +/*! \brief Function pointer for periodic sync pending check. */ +extern LctrPerSyncPendFn_t LctrMstPerSyncPending; + +/*! \brief Runtime configuration. */ extern const LlRtCfg_t *pLctrRtCfg; /************************************************************************************************** @@ -188,6 +210,9 @@ void LctrSetSupStates(void); void LctrMsgDispatcher(lctrMsgHdr_t *pMsg); void LctrEventHandler(uint8_t event); +/* Control */ +uint8_t LctrSetChannelClass(uint64_t chanMap); + /*! \} */ /* LL_LCTR_API */ #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_acad.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_acad.h new file mode 100644 index 00000000000..f038fcf00cd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_acad.h @@ -0,0 +1,85 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller ACAD definitions. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_ADV_ACAD_H +#define LCTR_API_ADV_ACAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief ACAD header */ +typedef struct +{ + uint8_t state; /*!< State of ACAD. */ + uint8_t opcode; /*!< Opcode of ACAD. */ + uint8_t len; /*!< Length of ACAD data field. */ +} LctrAcadHdr_t; + +/*! \brief ACAD data field for channel map update */ +typedef struct +{ + LctrAcadHdr_t hdr; /*!< ACAD header. */ + uint64_t chanMask; /*!< Channel mask for the update. */ + uint16_t instant; /*!< Instant for the update. */ +} LctrAcadChanMapUpd_t; + +/*! \brief ACAD data field for channel map update */ +typedef struct +{ + LctrAcadHdr_t hdr; /*!< ACAD header. */ + /* Reference values. */ + uint32_t bigAnchorPoint; /*!< BIG Anchor Point time. */ + /* ACAD fields. */ + uint16_t bigOffs; /*!< BIG offset. */ + uint8_t bigOffsUnits; /*!< BIG offset units. */ + uint16_t isoInter; /*!< ISO interval in units of 1.25ms. */ + uint8_t numBis; /*!< Number of BISs. */ + uint8_t nse; /*!< Number of subevents. */ + uint8_t bn; /*!< Burst number. */ + uint32_t subEvtInterUsec; /*!< Subevent interval in microseconds. */ + uint8_t pto; /*!< Pre-transmission offset. */ + uint32_t bisSpaceUsec; /*!< BIS spacing in microseconds. */ + uint8_t irc; /*!< Immediate repetition count. */ + uint16_t maxPdu; /*!< Maximum PDU size. */ + uint32_t seedAccAddr; /*!< Seed access address. */ + uint32_t sduInterUsec; /*!< SDU interval in microseconds. */ + uint16_t maxSdu; /*!< Maximum SDU size. */ + uint16_t baseCrcInit; /*!< Base CRC init. */ + uint64_t chanMap; /*!< Channel map. */ + uint8_t phy; /*!< PHY used by BIG. */ + uint64_t bisPldCtr; /*!< BIS payload counter. */ + uint8_t framing; /*!< BIG carries framed or unframed data. */ + uint8_t encrypt; /*!< Encryption mode of the BISes in the BIG. */ + uint8_t giv[LL_GIV_LEN]; /*!< GIV. */ + uint8_t gskd[LL_GSKD_LEN]; /*!< GSKD. */ +} LctrAcadBigInfo_t; + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_ADV_ACAD_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master.h index fb4cc228023..ec92af3ba88 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller scanning master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master_ae.h index 40f666dceae..daf7cc85a98 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_master_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller extended scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller extended scanning master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -195,7 +196,6 @@ void LctrMstExtScanSetScanPhy(uint8_t scanPhy); void LctrMstExtScanClearScanPhy(uint8_t scanPhy); void LctrMstExtScanSetParam(uint8_t scanPhy, uint8_t ownAddrType, uint8_t scanFiltPolicy, const LlExtScanParam_t *pParam); bool_t LctrMstExtScanIsEnabled(uint8_t scanPhy); -bool_t LctrMstExtScanIsPrivAddr(uint8_t scanPhy); bool_t LctrMstPerIsSyncPending(void); bool_t LctrMstPerIsSyncDisabled(void); bool_t LctrMstPerIsSync(uint8_t advSID, uint8_t advAddrType, uint64_t advAddr); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave.h index a84a647aeff..9b3f29d926c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller advertising slave interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller advertising slave interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave_ae.h index 03f09ce6b5e..058335e96bc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_adv_slave_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller extended advertising slave interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller extended advertising slave interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,7 +45,7 @@ enum /* Advertising events */ LCTR_EXT_ADV_MSG_START, /*!< Extended advertising start API event. */ LCTR_EXT_ADV_MSG_STOP, /*!< Extended advertising stop API event. */ - LCTR_EXT_ADV_MSG_INT_START, /*!< Extended advertising start internal event. */ // TODO not needed + LCTR_EXT_ADV_MSG_INT_START, /*!< Extended advertising start internal event. */ LCTR_EXT_ADV_MSG_TERMINATE, /*!< Extended advertising BOD terminated event. */ LCTR_EXT_ADV_MSG_TMR_DUR_EXP, /*!< Extended advertising duration timer expired event. */ LCTR_EXT_ADV_MSG_TOTAL /*!< Total number of extended advertising events. */ @@ -62,14 +63,24 @@ enum LCTR_PER_ADV_MSG_TOTAL /*!< Total number of periodic advertising events. */ }; -/*! \brief Acad dispatcher messages */ +/*! \brief ACAD dispatcher messages */ enum { LCTR_ACAD_MSG_CHAN_UPDATE, /* Start a channel map update */ LCTR_ACAD_MSG_CHAN_UPDATE_FINISH, /* Finish a channel map update */ + LCTR_ACAD_MSG_BIG_CREATED, /* BIG is created*/ + LCTR_ACAD_MSG_BIG_TERMINATED, /* BIG is terminated */ LCTR_ACAD_MSG_TOTAL }; +/*! \brief Link layer controller message data. */ +typedef union +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + lctrChanMapUpdate_t chanMapUpd; /*!< ACAD channel map update. */ + lctrBigCreated_t bigCreated; /*!< ACAD BIG created. */ +} lctrAcadSlvMsg_t; + /************************************************************************************************** Data Types **************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_master.h new file mode 100644 index 00000000000..43c367cac0e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_master.h @@ -0,0 +1,102 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller BIS slave interface file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_BIS_H +#define LCTR_API_BIS_H + +#include "lctr_api.h" +#include "lctr_api_adv_acad.h" +#include "cfg_mac_ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \addtogroup LL_LCTR_API_BIS + * \{ + */ + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief BIG task messages for \a LCTR_DISP_BIG_SYNC dispatcher. */ +typedef enum +{ + /* Broadcast events */ + LCTR_MST_BIG_MSG_RESET = LCTR_MSG_RESET, + /* Host/API events */ + LCTR_MST_BIG_API_CREATE_SYNC, /*!< BIG Create Sync API event. */ + LCTR_MST_BIG_API_TERMINATE_SYNC, /*!< BIG Terminate Sync API event. */ + /* Receive remote events */ + LCTR_MST_BIG_ACAD_BIG_INFO, /*!< BIG Info received. */ + LCTR_MST_BIG_PDU_TERM, /*!< Remote terminate received. */ + /* Internal events */ + LCTR_MST_BIG_INT_SYNC_TIMEOUT, /*!< BIG Sync timeout expired. */ + LCTR_MST_BIG_INT_MIC_FAILED, /*!< BIS PDU received with MIC failure. */ + LCTR_MST_BIG_INT_TERMINATED_SYNC, /*!< BIG Sync termination complete. */ + + LCTR_MST_BIG_MSG_TOTAL /*!< Total number of BIG events. */ +} LctrMstBigMsg_t; + +/*! \brief Minimum BIS Handle number. */ +#define LL_MIN_BIS 0x01 + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief ACAD BIG Info message. */ +typedef struct +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + LctrAcadBigInfo_t data; /*!< BIG Info data. */ +} LctrBigInfoMsg_t; + +/*! \brief BIG messages. */ +typedef union +{ + lctrMsgHdr_t hdr; /*!< Common message header. */ + LctrBigInfoMsg_t bigInfo; /*!< BIG Info message. */ +} lctrMstBigMsg_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void LctrMstBisInit(void); + +/* Control */ +uint8_t LctrMstBigCreateSync(LlBigCreateSync_t *pParam); +void LctrMstBigTerminateSync(uint8_t bisHandle); + +#ifdef __cplusplus +}; +#endif + +/*! \} */ /* LL_LCTR_API_BIS */ + +#endif /* LCTR_API_BIS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_slave.h new file mode 100644 index 00000000000..d43acb8b88d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_bis_slave.h @@ -0,0 +1,82 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller BIS slave interface file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_BIS_SLAVE_H +#define LCTR_API_BIS_SLAVE_H + +#include "lctr_api.h" +#include "cfg_mac_ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Slave BIS broadcasting task messages for \a LCTR_DISP_BIG_BCST dispatcher. */ +enum +{ + /* Broadcast events */ + LCTR_SLV_BIG_MSG_RESET = LCTR_MSG_RESET, /*!< Reset API message. */ + /* Host/API events */ + LCTR_SLV_BIG_MSG_CREATE_BIG, /*!< BIG slave creates BIG API event. */ + LCTR_SLV_BIG_MSG_CH_MAP_UPD, /*!< BIG channel map update. */ + LCTR_SLV_BIG_MSG_TERMINATE_BIG, /*!< BIG slave terminates BIG API event. */ + /* Internal events */ + LCTR_SLV_BIG_MSG_TERMINATED, /*!< BIG slave terminated internal event. */ + + LCTR_SLV_BIG_MSG_TOTAL /*!< Total number of BIG slave broadcasting events. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief BIG slave message data. */ +typedef union +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + lctrMsgHdr_t term; /*!< Terminate BIG message data. */ +} LctrSlvBigMsg_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +uint16_t LctrInitBisMem(uint8_t *pFreeMem, uint32_t freeMemSize); +void LctrSlvBisInit(void); + +/* Control */ +uint8_t LctrSlvBisCreateBig(LlCreateBig_t *pCreateBit); +uint8_t LctrSlvBisCreateBigTest(LlCreateBigTest_t *pCreateBigTest); +uint8_t LctrSlvBisTerminateBig(uint8_t bigHandle, uint8_t reason); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_BIS_SLAVE_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis.h new file mode 100644 index 00000000000..638c96f89de --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis.h @@ -0,0 +1,98 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS slave interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_CIS_H +#define LCTR_API_CIS_H + +#include "lctr_api.h" +#include "lmgr_api_cis_slave.h" +#include "cfg_mac_ble.h" +#include "lmgr_api_iso.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Maximum value for maximum Data PDU length (spec limit is 251) */ +#define LCTR_CIS_MAX_DATA_LEN_MAX BB_DATA_PLD_MAX_LEN + +/*! \brief Data channel PDU length (header + payload + MIC). */ +#define LCTR_CIS_DATA_PDU_LEN(len) ((len) + LL_DATA_HDR_LEN + LL_DATA_MIC_LEN) + +/*! \brief Maximum data channel PDU length (header + payload + MIC). */ +#define LCTR_CIS_DATA_PDU_MAX_LEN LCTR_CIS_DATA_PDU_LEN(LCTR_CIS_MAX_DATA_LEN_MAX) + +/*! \brief Minimum data channel PDU length (header + payload + MIC). */ +#define LCTR_CIS_DATA_PDU_MIN_LEN LCTR_CIS_DATA_PDU_LEN(0) + +/*! \brief CIS messages. */ +enum +{ + /* Broadcast events */ + LCTR_CIS_MSG_RESET = LCTR_MSG_RESET, /*!< Reset API message. */ + /* Scan events */ + LCTR_CIS_MSG_CIS_EST, /*!< CIS established event. */ + LCTR_CIS_MSG_CIS_EST_FAIL, /*!< CIS establishment failed event. */ + LCTR_CIS_MSG_CIS_DISC, /*!< CIS disconnect event. */ + LCTR_CIS_MSG_CIS_CONN_FAIL, /*!< CIS connection fail to maintain event. */ + LCTR_CIS_MSG_CIS_CLOSED, /*!< CIS closed event. */ + LCTR_CIS_MSG_CIS_TERM_MIC_FAILED, /*!< CIS terminated due to MIC failiure event. */ + LCTR_CIS_MSG_TOTAL, /*!< Total number of CIS slave events. */ + LCTR_CIS_MSG_INVALID= 0xFF, /*!< Invalid CIS message. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Disconnect message. Make sure it has the same structure as lctrDisconnect_t. */ +typedef struct +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + uint8_t reason; /*!< Disconnect reason. */ +} lctrCisDisconnect_t; + +/*! \brief Link layer controller message data. */ +typedef union +{ + lctrMsgHdr_t hdr; /*!< Message header. */ + lctrCisDisconnect_t disc; /*!< Disconnect message data. */ +} lctrCisMsg_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void LctrCisSlvInit(); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_CIS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_master.h new file mode 100644 index 00000000000..5ff3fae961d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_master.h @@ -0,0 +1,52 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS master interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_CIS_MASTER_H +#define LCTR_API_CIS_MASTER_H + +#include "lctr_api.h" +#include "wsf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void LctrMstCisInit(); + +/* Control */ +uint8_t LctrSetCigParam(LlCisCigParams_t *pSetCigParam, uint16_t *pCisHandles); +uint8_t LctrSetCigParamTest(LlCisCigParamsTest_t *pSetCigParamTest, uint16_t *pCisHandles); +uint8_t LctrRemoveCig(uint8_t cigId); +uint8_t LctrCreateCis(uint8_t numCis, LlCisCreateCisParams_t *pCreateCisParam); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_CIS_MASTER_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_slave.h new file mode 100644 index 00000000000..f2f6f827191 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_cis_slave.h @@ -0,0 +1,50 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS slave interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_CIS_SLAVE_H +#define LCTR_API_CIS_SLAVE_H + +#include "lctr_api.h" +#include "cfg_mac_ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +uint16_t LctrInitCisMem(uint8_t *pFreeMem, uint32_t freeMemSize); + +/* Control */ +uint8_t LctrRejectCisReq(uint16_t cisHandle, uint8_t reason); +uint8_t LctrAcceptCisReq(uint16_t cisHandle); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_CIS_SLAVE_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn.h index 3c1d6ceb3a8..578e96c1268 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller connection interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -52,6 +53,9 @@ extern "C" { /*! \brief Maximum value for maximum Data PDU length (spec limit is 251) */ #define LCTR_MAX_DATA_LEN_MAX BB_DATA_PLD_MAX_LEN +/*! \brief Maximum handle index (CIS included). */ +#define LCTR_MAX_HANDLE_INDEX (pLctrRtCfg->maxConn + pLctrRtCfg->maxCis) + /*! \brief Connected task messages for \a LCTR_DISP_CONN dispatcher. */ enum { @@ -83,6 +87,7 @@ enum LCTR_CONN_MSG_API_CIS_REQ, /*!< CIS request API event. */ LCTR_CONN_MSG_API_CIS_REQ_ACCEPT, /*!< Peer CIS request accept API event. */ LCTR_CONN_MSG_API_CIS_REQ_REJECT, /*!< Peer CIS request accept API event. */ + LCTR_CONN_MSG_API_PWR_CTRL_REQ, /*!< Peer power control request API event. */ /* Internal events */ _LCTR_CONN_INT_EVENTS = 40, @@ -95,6 +100,7 @@ enum LCTR_CONN_LLCP_VERSION_EXCH, /*!< LL initiated remote version exchange. */ LCTR_CONN_LLCP_FEATURE_EXCH, /*!< LL initiated remote feature exchange. */ LCTR_CONN_LLCP_LENGTH_EXCH, /*!< LL initiated data length exchange. */ + LCTR_CONN_LLCP_PWR_CTRL_REQ, /*!< LL initiated power control request. */ LCTR_CONN_LLCP_TERM, /*!< LL initiated termination. */ LCTR_CONN_LLCP_PROC_CMPL, /*!< LLCP procedure completed. */ LCTR_CONN_LLCP_START_PENDING, /*!< Start pending LLCP procedure. */ @@ -106,6 +112,7 @@ enum LCTR_CONN_TERM_INST_PASSED, /*!< Terminate connection due to instant passed. */ LCTR_CONN_TERM_CIS_LOCAL_RESOURCE, /*!< Terminate CIS connection due to local resource limitation. */ LCTR_CONN_TERMINATED, /*!< Connection event terminated. */ + LCTR_CONN_INIT_CANCELED, /*!< Connection cancelled event. */ _LCTR_CONN_TMR_EVENTS = 80, LCTR_CONN_TMR_LLCP_RSP_EXP, /*!< LLCP response timer expired. */ LCTR_CONN_TMR_CIS_LLCP_RSP_EXP, /*!< CIS LLCP response timer expired. */ @@ -214,7 +221,6 @@ typedef struct typedef struct { lctrMsgHdr_t hdr; /*!< Message header. */ -// uint16_t cisHandle; /*!< CIS handle. */ uint8_t reason; /*!< Reject reason. */ } lctrRejCisReq_t; @@ -226,6 +232,14 @@ typedef struct uint16_t cisHandle; /*!< CIS handle. */ } lctrCisDisc_t; +/*! \brief Internal power control request message. */ +typedef struct +{ + lctrMsgHdr_t hdr; /*!< Message Header. */ + int8_t delta; /*!< Delta requested. */ + uint8_t phy; /*!< PHY requested. */ +} lctrMsgPwrCtrlReq_t; + /*! \brief Link layer controller message data. */ typedef union { @@ -243,6 +257,7 @@ typedef union lctrSetMinUsedChan_t setMinUsedChan; /*!< Set minimum number of used channels message data. */ lctrPerAdvSyncTrsf_t perAdvSyncTrsf; /*!< Periodic advertising sync transfer data. */ lctrScaReq_t scaReq; /*!< Sleep clock accuracy request. */ + lctrMsgPwrCtrlReq_t pwrCtrlReq; /*!< Power control request. */ /* CIS */ lctrCreateCis_t createCis; /*!< Create CIS message data. */ @@ -305,6 +320,7 @@ bool_t LctrIsConnHandleEnabled(uint16_t handle); bool_t LctrIsCisConnHandleEnabled(uint16_t handle); uint8_t LctrGetRole(uint16_t handle); int8_t LctrGetRssi(uint16_t handle); +uint8_t lctrSetTxPowerReporting(uint16_t handle, uint8_t enableLocal, uint8_t enableRemote); int8_t LctrGetTxPowerLevel(uint16_t handle); uint64_t LctrGetChannelMap(uint16_t handle); uint64_t LctrGetUsedFeatures(uint16_t handle); @@ -314,14 +330,17 @@ void LctrGetPeerMinUsedChan(uint16_t handle, uint8_t *pPeerMinUsedChan); bool_t LctrIsWaitingForReply(uint16_t handle, uint8_t reply); bool_t LctrIsCisEnabled(uint16_t handle); - /* Control */ void LctrSetTxPowerLevel(uint16_t handle, int8_t level); +void LctrSetPhyTxPowerLevel(uint16_t handle, int8_t level, uint8_t phy); +int8_t LctrGetPhyTxPowerLevel(uint16_t handle, uint8_t phy); uint32_t LctrGetAuthPayloadTimeout(uint16_t handle); bool_t LctrSetAuthPayloadTimeout(uint16_t handle, uint32_t timeoutMs); void LctrGetEncMode(uint16_t handle, LlEncMode_t *pMode); bool_t LctrSetEncMode(uint16_t handle, const LlEncMode_t *pMode); void LctrSetConnOpFlags(uint16_t handle, uint32_t flags, bool_t enable); +uint8_t lctrSetPowerMonitorEnable(uint16_t handle, bool_t enable); + /* Data path */ void LctrTxAcl(uint8_t *pAclBuf); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn_cs2.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn_cs2.h index e58eca5ae3f..b58f6170221 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn_cs2.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_conn_cs2.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller channel selection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller channel selection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master.h index ecabac3faf0..562f16b26c9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller initiating master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller initiating master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master_ae.h index 2c31f7fab89..5bc5c211cfb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_init_master_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller extended initiating master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller extended initiating master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -40,11 +41,6 @@ extern "C" { /************************************************************************************************** Constants **************************************************************************************************/ -/*! \brief Change supervision timeout value to us. */ -#define LL_SUP_TIMEOUT_VAL_TO_US(x) x * 10000 - -/*! \brief Change connection interval value to us. */ -#define LL_CONN_INTERVAL_VAL_TO_US(x) x * 1250 /*! \brief Master extended initiate task messages for \a LCTR_DISP_EXT_INIT dispatcher. */ enum diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_iso.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_iso.h new file mode 100644 index 00000000000..c7b6904bea3 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_iso.h @@ -0,0 +1,60 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller common ISO interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_ISO_H +#define LCTR_API_ISO_H + +#include "lctr_api.h" +#include "cfg_mac_ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +uint16_t LctrInitIsoMem(uint8_t *pFreeMem, uint32_t freeMemSize); +void LctrInitCodec(void); + +/* Data path */ +void LctrTxIso(uint8_t *pIsoBuf); +uint8_t *LctrRxIso(void); +void LctrRxIsoComplete(uint8_t numBufs); +uint8_t LctrReadIsoTxSync(uint16_t handle, uint16_t *pPktSn, uint32_t *pTs, uint32_t *pTimeOffs); +uint8_t LctrSetupIsoDataPath(LlIsoSetupDataPath_t *pSetupDataPath); +uint8_t LctrRemoveIsoDataPath(uint16_t handle, uint8_t dpDir); +uint8_t LctrIsoTxTest(uint16_t handle, uint8_t pldType); +uint8_t LctrIsoRxTest(uint16_t handle, uint8_t pldType); +uint8_t LctrIsoReadTestCounter(uint16_t handle, LlIsoTestCtrs_t *pStats); +uint8_t LctrIsoTestEnd(uint16_t handle, LlIsoTestCtrs_t *pStats); +uint8_t LctrReadIsoLinkQual(uint16_t handle, LlIsoLinkQual_t *pStats); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_ISO_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_pc.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_pc.h new file mode 100644 index 00000000000..4bfb8b8a3eb --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_pc.h @@ -0,0 +1,47 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller power control interface file. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_API_PC_H +#define LCTR_API_PC_H + +#include "lctr_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization functions. */ +void LctrPowerControlInit(void); + +/* HCI functions. */ +uint8_t lctrSetPathLossReportingParams(uint16_t handle, uint8_t highThresh, uint8_t highHyst, uint8_t lowThresh, uint8_t lowHyst, uint16_t minTime); +uint8_t lctrSetPathLossReportingEnable(uint16_t handle, uint8_t enable); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_API_PC_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_phy.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_phy.h index aca0792686a..8b1fdb8306a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_phy.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_phy.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller PHY features interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller PHY features interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_priv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_priv.h index 5cf1b168089..f4645b2770e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_priv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_priv.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller privacy interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller privacy interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_sc.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_sc.h index a2ce015a28a..731d6e77c05 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_sc.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lctr_api_sc.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller secure connections interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller secure connections interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api.h index 06a17e6e9c0..c9a6b202d10 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager common interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager common interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -74,6 +75,8 @@ typedef struct uint16_t perScanCtxSize; /*!< Size of the periodic scanning context. */ uint16_t cisCtxSize; /*!< Size of the CIS context. */ uint16_t cigCtxSize; /*!< Size of the CIG context. */ + uint16_t bisCtxSize; /*!< Size of the BIS context. */ + uint16_t bigCtxSize; /*!< Size of the BIG context. */ uint64_t featuresDefault; /*!< Default supported features. */ llIsoCback_t sendIsoCompCback; /*!< ISO data send complete callback. */ @@ -126,22 +129,22 @@ typedef struct int8_t powerThreshold[LL_MAX_PHYS]; /*!< Power threshold for each PHY. */ uint8_t localMinUsedChan[LL_MAX_PHYS]; /*!< Local minimum number of used channels for each PHY. */ - uint8_t hciSupCommands[HCI_SUP_CMD_LEN]; /*!< Supported HCI commands bit mask. */ + /* Isochronous channels. */ + bool_t sendIsoCmplEvt; /*!< ISO event completion notification generation enable. */ } lmgrCtrlBlk_t; /*! \brief Channel parameters. */ typedef struct { /* Channel parameters */ - uint8_t lastChanIdx; /*!< Current channel index. */ - uint8_t numUsedChan; /*!< Number of used channels. */ uint64_t chanMask; /*!< Channel mask. */ uint8_t chanRemapTbl[LL_CHAN_DATA_MAX_IDX + 1]; /*!< Channel remapping table. */ + uint8_t numUsedChan; /*!< Number of used channels. */ uint8_t usedChSel; /*!< Used channel selection. */ uint16_t chIdentifier; /*!< Channel identifier. */ - /* For subevent calculation only */ + /* Subevent parameters */ uint16_t prnLast; /*!< Last used permutation. */ uint8_t subEvtIdx; /*!< Subevent index. */ } lmgrChanParam_t; @@ -178,9 +181,7 @@ bool_t LmgrIsExtCommandAllowed(void); /* Utility */ void LmgrBuildRemapTable(lmgrChanParam_t *pChanParam); uint8_t LmgrSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t eventCounter, uint16_t numSkip, bool_t calSubEvt); -uint32_t LmgrCalcWindowWideningUsec(uint32_t unsyncTimeUsec, uint32_t caPpm); uint8_t LmgrSelectNextSubEvtChannel(lmgrChanParam_t *pChanParam); -uint8_t * LmgrReadHciSupCmd(void); /* Event Messages */ void LmgrSendAdvEnableCnf(uint8_t status); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master.h index f3504c09472..21f202cd896 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager advertising master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager advertising master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,8 +43,8 @@ extern "C" { /*! \brief Scan parameters. */ typedef struct { - uint16_t scanInterval; /*!< Scan interval in BB ticks. */ - uint16_t scanWindow; /*!< Scan window duration in BB ticks. */ + uint16_t scanInterval; /*!< Scan interval in BLE ticks. */ + uint16_t scanWindow; /*!< Scan window duration in BLE ticks. */ uint8_t scanType; /*!< Advertising type. */ uint8_t ownAddrType; /*!< Address type used by this device. */ uint8_t scanFiltPolicy; /*!< Scanning filter policy. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master_ae.h index c39d8c01a67..15329b885be 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_master_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager advertising extension interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager advertising extension interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave.h index 6c323adb8b3..565d00dd9ab 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager advertising slave interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager advertising slave interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,8 +43,8 @@ extern "C" { /*! \brief Advertising parameters. */ typedef struct { - uint32_t advInterMin; /*!< Minimum advertising interval. */ - uint32_t advInterMax; /*!< Maximum advertising interval. */ + uint32_t advInterMinUsec; /*!< Minimum advertising interval in microseconds. */ + uint32_t advInterMaxUsec; /*!< Maximum advertising interval in microseconds. */ uint8_t advType; /*!< Advertising type. */ uint8_t ownAddrType; /*!< Address type used by this device. */ uint8_t peerAddrType; /*!< Address type of peer device. Only used for directed advertising. */ @@ -55,7 +56,7 @@ typedef struct /*! \brief Slave role device parameter definition. */ typedef struct { - uint32_t advTermCntDown; /*!< Advertising termination count down. */ + uint32_t advTermCntDownUsec; /*!< Advertising termination count down in microseconds. */ lmgrAdvParam_t advParam; /*!< Advertising parameters. */ lmgrAdvbUser_t advData; /*!< Advertising host data buffer. */ lmgrAdvbUser_t scanRspData; /*!< Scan response host data buffer. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave_ae.h index e59e0fc8bf7..592378bbb10 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_adv_slave_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager advertising extension interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager advertising extension interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_master.h new file mode 100644 index 00000000000..3c71dccfd08 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_master.h @@ -0,0 +1,72 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer manager connected isochronous stream master interface file. + * + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LMGR_API_CIS_MASTER_H +#define LMGR_API_CIS_MASTER_H + +#include "lmgr_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \addtogroup LL_LMGR_API_CIS_MST + * \{ + */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ +/*! \brief Master role device parameter definition. */ +typedef struct +{ + uint8_t maxNumCis; /*!< Maximum number of CIS. */ + + bool_t createCisPend; /*!< TRUE if create CIS command is pending. */ + +} lmgrCisMstCtrlBlk_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ +extern lmgrCisMstCtrlBlk_t lmgrCisMstCb; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void LmgrMstCisInit(void); + +/* Status */ +uint8_t LmgrMstCisGetMaxNumCis(void); + +/*! \} */ /* LL_LMGR_API_CIS_MST */ + +#ifdef __cplusplus +}; +#endif + +#endif /* LMGR_API_CIS_MASTER_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_slave.h new file mode 100644 index 00000000000..7b03a9f42da --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_cis_slave.h @@ -0,0 +1,64 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer manager connected isochronous stream slave interface file. + * + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LMGR_API_CIS_SLAVE_H +#define LMGR_API_CIS_SLAVE_H + +#include "lmgr_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \addtogroup LL_LMGR_API_ADV_MST + * \{ + */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ +/*! \brief Slave role device parameter definition. */ +typedef struct +{ + uint8_t maxNumCis; /*!< Maximum number of CIS. */ +} lmgrCisSlvCtrlBlk_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +/* Initialization */ +void LmgrMstInit(void); + +/*! \} */ /* LL_LMGR_API_CIS_SLV */ + +#ifdef __cplusplus +}; +#endif + +#endif /* LMGR_API_CIS_SLAVE_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_conn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_conn.h index d723560c43c..c600a6982f8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_conn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_conn.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager connection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_iso.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_iso.h new file mode 100644 index 00000000000..654b02383f5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_iso.h @@ -0,0 +1,80 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer manager connection interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LMGR_API_ISO_H +#define LMGR_API_ISO_H + +#include "lmgr_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \addtogroup LL_LMGR_API_ISO + * \{ + */ + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Slave role device parameter definition. */ +typedef struct +{ + uint8_t availTxBuf; /*!< Available number of transmit buffers. */ + uint8_t availRxBuf; /*!< Available number of receive buffers. */ + + uint16_t maxTxLen; /*!< Default maximum number of Data PDU bytes. */ + uint16_t maxTxTime; /*!< Default maximum microseconds for a Data PDU. */ + + wsfQueue_t rxDataQ; /*!< Receive Data PDU queue. */ + + uint32_t dataPendMsk; /*!< Bitmask of connection handles with new pending data. */ + + uint8_t allPhys; /*!< Default all PHYs. */ + uint8_t txPhys; /*!< Default transmitter PHYs. */ + uint8_t rxPhys; /*!< Default receiver PHYs. */ + +} lmgrIsoCtrlBlk_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ +extern lmgrIsoCtrlBlk_t lmgrIsoCb; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Initialization */ +void LmgrIsoInit(void); + +/*! \} */ /* LMGR_API_ISO_H */ + +#ifdef __cplusplus +}; +#endif + +#endif /* LMGR_API_ISO_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_priv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_priv.h index b7979ac24cd..269bc085855 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_priv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_priv.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager privacy interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager privacy interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_sc.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_sc.h index acf7401ef08..a7201f878e1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_sc.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/include/lmgr_api_sc.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer manager secure connections interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer manager secure connections interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init.c index 45df5eda24d..abd7457505b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL initialization for SoC configuration. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL initialization for SoC configuration. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,6 +27,7 @@ #include "pal_bb_ble.h" #include "pal_radio.h" #include "sch_api.h" +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Functions @@ -34,8 +36,6 @@ /*************************************************************************************************/ /*! * \brief Initialize BB. - * - * \return None. */ /*************************************************************************************************/ void LlInitBbInit(void) @@ -74,32 +74,31 @@ void LlInitBbInit(void) #endif #endif - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) #ifdef INIT_CENTRAL BbBleCisMasterInit(); - #else - #ifdef INIT_OBSERVER - /* TODO BIS observer */ - #endif #endif - #ifdef INIT_PERIPHERAL BbBleCisSlaveInit(); - #else - #ifdef INIT_BROADCASTER - /* TODO BIS broadcaster */ - #endif + #endif + #ifdef INIT_OBSERVER + BbBleBisMasterInit(); + #endif + #ifdef INIT_BROADCASTER + BbBleBisSlaveInit(); #endif #endif BbBleTestInit(); + +#if (BB_SNIFFER_ENABLED == TRUE) + BbBleInitSniffer(BB_SNIFFER_OUTPUT_NULL_METHOD, FALSE); +#endif } /*************************************************************************************************/ /*! * \brief Initialize scheduler. - * - * \return None. */ /*************************************************************************************************/ void LlInitSchInit(void) @@ -111,8 +110,6 @@ void LlInitSchInit(void) /*************************************************************************************************/ /*! * \brief Initialize LL. - * - * \return None. */ /*************************************************************************************************/ void LlInitLlInit(void) @@ -154,24 +151,34 @@ void LlInitLlInit(void) LlExtScanMasterInit(); LlExtInitMasterInit(); LlPhyMasterInit(); - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) LlCisMasterInit(); + LlBisMasterInit(); + LlPowerControlInit(); #endif #else #ifdef INIT_OBSERVER LlExtScanMasterInit(); + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) + LlBisMasterInit(); + #endif #endif #endif #ifdef INIT_PERIPHERAL LlExtAdvSlaveInit(); LlPhySlaveInit(); - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) LlCisSlaveInit(); + LlBisSlaveInit(); + LlPowerControlInit(); #endif #else #ifdef INIT_BROADCASTER LlExtAdvSlaveInit(); + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) + LlBisSlaveInit(); + #endif #endif #endif @@ -274,15 +281,20 @@ uint32_t LlInitSetLlRtCfg(const LlRtCfg_t *pLlRtCfg, uint8_t *pFreeMem, uint32_t totalMemUsed += memUsed; #endif - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) memUsed = LlInitCisMem(pFreeMem, freeMemAvail); pFreeMem += memUsed; freeMemAvail -= memUsed; totalMemUsed += memUsed; + memUsed = LlInitBisMem(pFreeMem, freeMemAvail); + pFreeMem += memUsed; + freeMemAvail -= memUsed; + totalMemUsed += memUsed; + memUsed = LlInitIsoMem(pFreeMem, freeMemAvail); - /* pFreeMem += memUsed; - freeMemAvail -= memUsed; */ + /* pFreeMem += memUsed; */ + /* freeMemAvail -= memUsed; */ totalMemUsed += memUsed; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init_ctr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init_ctr.c index 98a8fa43000..9bab8d31861 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init_ctr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/init/init_ctr.c @@ -2,15 +2,16 @@ /*! * \brief LL initialization for controller configuration. * - * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -27,21 +28,16 @@ Functions **************************************************************************************************/ -/*! \brief Extended VS command decoder. */ -extern bool_t lhciVsExtDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); - /*************************************************************************************************/ /*! * \brief Initialize controller LHCI handler. - * - * \return None. */ /*************************************************************************************************/ void LlInitLhciHandler(void) { wsfHandlerId_t handlerId; -#if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) +#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) handlerId = WsfOsSetNextHandler(LhciIsoHandler); LhciIsoHandlerInit(handlerId); #else @@ -54,20 +50,19 @@ void LlInitLhciHandler(void) /*! * \brief Initialize controller HCI transport. * - * \return None. + * \param maxAclLen Maximum ACL data length. + * \param maxIsoSduLen Maximum ISO SDU data length. */ /*************************************************************************************************/ -void LlInitChciTrInit(void) +void LlInitChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen) { wsfHandlerId_t handlerId = WsfOsSetNextHandler(ChciTrHandler); - ChciTrHandlerInit(handlerId); + ChciTrHandlerInit(handlerId, maxAclLen, maxIsoSduLen); } /*************************************************************************************************/ /*! * \brief Initialize LL HCI. - * - * \return None. */ /*************************************************************************************************/ void LlInitLhciInit(void) @@ -102,15 +97,10 @@ void LlInitLhciInit(void) LhciScInit(); #endif - LhciVsExtInit(lhciVsExtDecodeCmdPkt); - #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_0) #ifdef INIT_CENTRAL LhciExtScanMasterInit(); LhciExtConnMasterInit(); - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) - LhciCisMasterInit(); - #endif #else #ifdef INIT_OBSERVER LhciExtScanMasterInit(); @@ -121,12 +111,6 @@ void LlInitLhciInit(void) LhciExtAdvSlaveInit(); #endif - #ifdef INIT_PERIPHERAL - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) - LhciCisSlaveInit(); - #endif - #endif - #if defined(INIT_PERIPHERAL) || defined(INIT_CENTRAL) LhciChannelSelection2Init(); LhciPhyInit(); @@ -138,7 +122,24 @@ void LlInitLhciInit(void) #endif #endif - #if (BT_VER >= LL_VER_BT_CORE_SPEC_MILAN) + #if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) + #ifdef INIT_CENTRAL + LhciCisMasterInit(); + LhciBisMasterInit(); + #else + #ifdef INIT_OBSERVER + LhciBisMasterInit(); + #endif + #endif + + #ifdef INIT_BROADCASTER + LhciBisSlaveInit(); + #endif + + #ifdef INIT_PERIPHERAL + LhciCisSlaveInit(); + #endif + LhciIsoInit(); #endif } @@ -158,9 +159,10 @@ uint32_t LlInitControllerInit(LlInitRtCfg_t *pCfg) totalMemUsed = LlInit(pCfg); - LlInitChciTrInit(); + LlInitChciTrInit(pCfg->pLlRtCfg->maxAclLen, pCfg->pLlRtCfg->maxIsoSduLen); LlInitLhciInit(); LlInitLhciHandler(); + LhciInitFinalize(); return totalMemUsed; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master.c index 2019a46260c..7c80ff47209 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master scan action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master scan action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,8 +38,6 @@ WSF_CT_ASSERT((LL_NUM_ADV_FILT <= 32)); * \brief Common scan resource cleanup. * * \param pCtx Scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrScanCleanup(lctrMstScanCtx_t *pCtx) @@ -81,8 +80,6 @@ void lctrScanCleanup(lctrMstScanCtx_t *pCtx) /*************************************************************************************************/ /*! * \brief Start scan discovery. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActDiscover(void) @@ -117,8 +114,6 @@ void lctrScanActDiscover(void) /*************************************************************************************************/ /*! * \brief Shutdown active scan operation. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActShutdown(void) @@ -139,8 +134,6 @@ void lctrScanActShutdown(void) /*************************************************************************************************/ /*! * \brief Send scan operation confirm. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActScanCnf(void) @@ -151,8 +144,6 @@ void lctrScanActScanCnf(void) /*************************************************************************************************/ /*! * \brief Send disallow scan host notification. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActDisallowScan(void) @@ -163,8 +154,6 @@ void lctrScanActDisallowScan(void) /*************************************************************************************************/ /*! * \brief Operation self terminated (e.g. on connection indication). - * - * \return None. */ /*************************************************************************************************/ void lctrScanActSelfTerm(void) @@ -176,8 +165,6 @@ void lctrScanActSelfTerm(void) /*************************************************************************************************/ /*! * \brief Terminated scan after host scan disable. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActScanTerm(void) @@ -191,8 +178,6 @@ void lctrScanActScanTerm(void) /*************************************************************************************************/ /*! * \brief Terminated scan after host reset. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActResetTerm(void) @@ -204,8 +189,6 @@ void lctrScanActResetTerm(void) /*************************************************************************************************/ /*! * \brief Update scan parameters. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActUpdateScanParam(void) @@ -218,8 +201,6 @@ void lctrScanActUpdateScanParam(void) /*************************************************************************************************/ /*! * \brief Update scan filter. - * - * \return None. */ /*************************************************************************************************/ void lctrScanActUpdateScanFilt(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master_ae.c index 0b0c40ba97a..e9923bc177b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller master scan action routines. + * \file + * + * \brief Link layer controller master scan action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,6 +27,7 @@ #include "lctr_api_adv_master_ae.h" #include "lmgr_api_adv_master_ae.h" #include "sch_api.h" +#include "sch_api_ble.h" #include "wsf_assert.h" #include "wsf_msg.h" #include "wsf_trace.h" @@ -38,7 +40,8 @@ * \brief Setup periodic scanning context. * * \param pPerCreateSync Create sync control block. - * \param pMsg Create sync messgae. + * \param pMsg Create sync message. + * \param createDispId Dispatcher ID. * * \return TRUE if successful, FALSE otherwise. */ @@ -83,7 +86,7 @@ static bool_t lctrPerAdvSyncEstRptPack(lctrPerScanCtx_t *pPerScanCtx, lmgrPerAdv Bda64ToBstream(pRpt->addr, pPerScanCtx->advAddr); pRpt->addrType = pPerScanCtx->advAddrType; pRpt->advPhy = pPerScanCtx->rxPhys; - pRpt->advInterval = LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pPerScanCtx->perInter)); + pRpt->advInterval = LCTR_PER_INTER_TO_MS(pPerScanCtx->perInterUsec); pRpt->advClkAccuracy = pPerScanCtx->sca; return TRUE; @@ -94,14 +97,19 @@ static bool_t lctrPerAdvSyncEstRptPack(lctrPerScanCtx_t *pPerScanCtx, lmgrPerAdv * \brief Common periodic scan resource cleanup. * * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstPerScanCleanupOp(lctrPerScanCtx_t *pPerScanCtx) { BbStop(BB_PROT_BLE); + if (pPerScanCtx->termCback) + { + pPerScanCtx->termCback(LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx)); + } + + SchTmRemove(LCTR_GET_PER_SCAN_TM_HANDLE(pPerScanCtx)); + if (pPerScanCtx->filtParam.filterPolicy) { LmgrDecPeriodiclistRefCount(); @@ -117,8 +125,6 @@ static void lctrMstPerScanCleanupOp(lctrPerScanCtx_t *pPerScanCtx) * \brief Common scan resource cleanup. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtScanCleanupOp(lctrExtScanCtx_t *pExtScanCtx) @@ -157,8 +163,6 @@ static void lctrMstExtScanCleanupOp(lctrExtScanCtx_t *pExtScanCtx) * \brief Start scan discovery. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtScanActDiscover(lctrExtScanCtx_t *pExtScanCtx) @@ -206,8 +210,6 @@ void lctrExtScanActDiscover(lctrExtScanCtx_t *pExtScanCtx) * \brief Update scan discovery. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtScanActUpdateDiscover(lctrExtScanCtx_t *pExtScanCtx) @@ -220,24 +222,33 @@ void lctrExtScanActUpdateDiscover(lctrExtScanCtx_t *pExtScanCtx) * \brief Shutdown active scan operation. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtScanActShutdown(lctrExtScanCtx_t *pExtScanCtx) { + const uint8_t scanPhyIndex = (LCTR_GET_EXT_SCAN_HANDLE(pExtScanCtx) == LCTR_SCAN_PHY_CODED) ? LCTR_SCAN_PHY_CODED : LCTR_SCAN_PHY_1M; + pExtScanCtx->shutdown = TRUE; - if (!pExtScanCtx->auxOpPending) + if (scanPhyIndex == lctrActiveExtScan.scanIndex) { - SchRemove(&pExtScanCtx->scanBod); + if (!pExtScanCtx->auxOpPending) + { + SchRemove(&pExtScanCtx->scanBod); + } + else + { + SchRemove(&pExtScanCtx->auxScanBod); + } + + /* Shutdown completes with events generated in BOD end callback. */ } else { - SchRemove(&pExtScanCtx->auxScanBod); + /* BOD of this scan context is not scheduled. No need to remove it. */ + lctrActiveExtScan.scanMask &= ~(1 << scanPhyIndex); + lctrSendExtScanMsg(pExtScanCtx, LCTR_EXT_SCAN_MSG_TERMINATE); } - - /* Shutdown completes with events generated in BOD end callback. */ } /*************************************************************************************************/ @@ -245,8 +256,6 @@ void lctrExtScanActShutdown(lctrExtScanCtx_t *pExtScanCtx) * \brief Send scan operation confirm. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtScanActScanCnf(lctrExtScanCtx_t *pExtScanCtx) @@ -256,11 +265,29 @@ void lctrExtScanActScanCnf(lctrExtScanCtx_t *pExtScanCtx) /*************************************************************************************************/ /*! - * \brief Send disallow scan host notification. + * \brief Terminate a restarting scan (scan in terminate state due to controller-issued terminate). * * \param pExtScanCtx Extended scan context. + */ +/*************************************************************************************************/ +void lctrExtScanHostDisable(lctrExtScanCtx_t *pExtScanCtx) +{ + if (lctrMstExtScan.scanTermByHost > 1) + { + LmgrSendExtScanEnableCnf(LL_ERROR_CODE_CMD_DISALLOWED); + return; + } + + /* Start/Restart timers. */ + WsfTimerStop(&lctrMstExtScan.tmrScanDur); + WsfTimerStop(&lctrMstExtScan.tmrScanPer); +} + +/*************************************************************************************************/ +/*! + * \brief Send disallow scan host notification. * - * \return None. + * \param pExtScanCtx Extended scan context. */ /*************************************************************************************************/ void lctrExtScanActDisallowScan(lctrExtScanCtx_t *pExtScanCtx) @@ -273,11 +300,29 @@ void lctrExtScanActDisallowScan(lctrExtScanCtx_t *pExtScanCtx) /*************************************************************************************************/ /*! - * \brief Terminated scan after host scan disable. + * \brief Send enable during terminate state. * * \param pExtScanCtx Extended scan context. + */ +/*************************************************************************************************/ +void lctrExtScanActHostEnable(lctrExtScanCtx_t *pExtScanCtx) +{ + if (lctrMstExtScan.scanTermByHost) + { + LmgrSendExtScanEnableCnf(LL_ERROR_CODE_CMD_DISALLOWED); + } + else + { + LmgrSendExtScanEnableCnf(LL_SUCCESS); + } + +} + +/*************************************************************************************************/ +/*! + * \brief Terminated scan after host scan disable. * - * \return None. + * \param pExtScanCtx Extended scan context. */ /*************************************************************************************************/ void lctrExtScanActScanTerm(lctrExtScanCtx_t *pExtScanCtx) @@ -295,8 +340,6 @@ void lctrExtScanActScanTerm(lctrExtScanCtx_t *pExtScanCtx) * \brief Terminated scan after internal scan disable. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtScanActSelfTerm(lctrExtScanCtx_t *pExtScanCtx) @@ -307,8 +350,6 @@ void lctrExtScanActSelfTerm(lctrExtScanCtx_t *pExtScanCtx) /*************************************************************************************************/ /*! * \brief Create sync action function. - * - * \return None. */ /*************************************************************************************************/ void lctrCreateSyncActCreate(void) @@ -336,8 +377,6 @@ void lctrCreateSyncActCreate(void) /*************************************************************************************************/ /*! * \brief Create sync done action function. - * - * \return None. */ /*************************************************************************************************/ void lctrCreateSyncActDone(void) @@ -351,8 +390,6 @@ void lctrCreateSyncActDone(void) /*************************************************************************************************/ /*! * \brief Create sync cancel action function. - * - * \return None. */ /*************************************************************************************************/ void lctrCreateSyncActCancel(void) @@ -370,8 +407,6 @@ void lctrCreateSyncActCancel(void) /*************************************************************************************************/ /*! * \brief Create sync failed action function. - * - * \return None. */ /*************************************************************************************************/ void lctrCreateSyncActFailed(void) @@ -394,8 +429,6 @@ void lctrCreateSyncActFailed(void) /*************************************************************************************************/ /*! * \brief Create sync terminate action function. - * - * \return None. */ /*************************************************************************************************/ void lctrCreateSyncActTerminate(void) @@ -418,8 +451,6 @@ void lctrCreateSyncActTerminate(void) /*************************************************************************************************/ /*! * \brief Transfer sync start action function. - * - * \return None. */ /*************************************************************************************************/ void lctrTransferSyncActStart(void) @@ -449,7 +480,7 @@ void lctrTransferSyncActStart(void) /* Decode syncInfo */ lctrUnpackSyncInfo(&trsfSyncInfo, pMsg->bSyncInfo); - pPerScanCtx->perInter = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(trsfSyncInfo.syncInter)); + pPerScanCtx->perInterUsec = LCTR_PER_INTER_TO_US(trsfSyncInfo.syncInter); pPerScanCtx->advSID = pMsg->advSID; pPerScanCtx->advAddrType = pMsg->advAddrType; pPerScanCtx->advAddr = pMsg->advAddr; @@ -492,8 +523,6 @@ void lctrTransferSyncActStart(void) /*************************************************************************************************/ /*! * \brief Transfer sync done action function. - * - * \return None. */ /*************************************************************************************************/ void lctrTransferSyncActDone(void) @@ -503,8 +532,6 @@ void lctrTransferSyncActDone(void) /*************************************************************************************************/ /*! * \brief Transfer sync failed action function. - * - * \return None. */ /*************************************************************************************************/ void lctrTransferSyncActFailed(void) @@ -519,8 +546,6 @@ void lctrTransferSyncActFailed(void) /*************************************************************************************************/ /*! * \brief Transfer sync cancel action function. - * - * \return None. */ /*************************************************************************************************/ void lctrTransferSyncActCancel(void) @@ -532,8 +557,6 @@ void lctrTransferSyncActCancel(void) /*************************************************************************************************/ /*! * \brief Transfer sync terminate action function. - * - * \return None. */ /*************************************************************************************************/ void lctrTransferSyncActTerminate(void) @@ -551,8 +574,6 @@ void lctrTransferSyncActTerminate(void) * \brief Periodic scanning sync established action function. * * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrPerScanActSyncEstd(lctrPerScanCtx_t *pPerScanCtx) @@ -577,8 +598,6 @@ void lctrPerScanActSyncEstd(lctrPerScanCtx_t *pPerScanCtx) * \brief Periodic scanning sync terminate action function. * * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrPerScanActSyncTerminate(lctrPerScanCtx_t *pPerScanCtx) @@ -595,8 +614,6 @@ void lctrPerScanActSyncTerminate(lctrPerScanCtx_t *pPerScanCtx) * \brief Periodic scanning sync terminate done action function. * * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrPerScanActSyncTerminateDone(lctrPerScanCtx_t *pPerScanCtx) @@ -609,8 +626,6 @@ void lctrPerScanActSyncTerminateDone(lctrPerScanCtx_t *pPerScanCtx) * \brief Periodic scanning sync terminate action function. * * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrPerScanActSyncTimeout(lctrPerScanCtx_t *pPerScanCtx) @@ -628,31 +643,38 @@ void lctrPerScanActSyncTimeout(lctrPerScanCtx_t *pPerScanCtx) /*************************************************************************************************/ /*! - * \brief Process acad that need to be serviced. + * \brief Process ACAD that need to be serviced. * - * \param pMsg Acad message. - * - * \return None + * \param pMsg ACAD message. */ /*************************************************************************************************/ void lctrPerScanActProcessAcad(lctrAcadMsg_t *pMsg) { lctrPerScanCtx_t *pPerScanCtx = LCTR_GET_PER_SCAN_CTX(pMsg->hdr.handle); - switch(pMsg->hdr.acadId) + + switch (pMsg->hdr.acadId) { case LCTR_ACAD_ID_CHAN_MAP_UPDATE: { - lctrAcadChanMapUpd_t *pData = &pPerScanCtx->acadParams[pMsg->hdr.acadId].chanMapUpdate; + LctrAcadChanMapUpd_t *pChanMapUpd = &pPerScanCtx->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE].chanMapUpdate; - if ((pData->instant - pMsg->hdr.eventCtr) <= pMsg->hdr.skip) + if ((pChanMapUpd->instant - pMsg->hdr.eventCtr) <= pMsg->hdr.skip) { - pPerScanCtx->chanParam.chanMask = pData->chanMask; + pPerScanCtx->chanParam.chanMask = pChanMapUpd->chanMask; LmgrBuildRemapTable(&pPerScanCtx->chanParam); - pData->hdr.state = LCTR_ACAD_STATE_DISABLED; + pChanMapUpd->hdr.state = LCTR_ACAD_STATE_DISABLED; } break; } + case LCTR_ACAD_ID_BIG_INFO: + { + LctrAcadBigInfo_t *pBigInfo = &pPerScanCtx->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + /* No action required. */ + pBigInfo->hdr.state = LCTR_ACAD_STATE_DISABLED; + break; + } + default: break; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave.c index a70282b20bd..6d8ab374228 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -33,8 +34,6 @@ /*************************************************************************************************/ /*! * \brief Notify host of direct connect timeout failure. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyHostDirectConnectTimeout(void) @@ -69,8 +68,6 @@ static void lctrNotifyHostDirectConnectTimeout(void) /*************************************************************************************************/ /*! * \brief Common advertise resource cleanup. - * - * \return None. */ /*************************************************************************************************/ static void lctrAdvCleanup(void) @@ -86,8 +83,6 @@ static void lctrAdvCleanup(void) /*************************************************************************************************/ /*! * \brief Start advertising. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActStart(void) @@ -108,8 +103,6 @@ void lctrAdvActStart(void) /*************************************************************************************************/ /*! * \brief Start advertising. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActSelfStart(void) @@ -128,8 +121,6 @@ void lctrAdvActSelfStart(void) /*************************************************************************************************/ /*! * \brief Shutdown active advertising operation. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActShutdown(void) @@ -150,8 +141,6 @@ void lctrAdvActShutdown(void) /*************************************************************************************************/ /*! * \brief Send advertising operation confirm. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActAdvCnf(void) @@ -162,8 +151,6 @@ void lctrAdvActAdvCnf(void) /*************************************************************************************************/ /*! * \brief Send advertising operation command disallowed. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActDisallowAdvCnf(void) @@ -175,8 +162,6 @@ void lctrAdvActDisallowAdvCnf(void) /*! * \brief Operation self terminated (e.g. on connection indication). * - * \return None. - * * Slave self-termination is a result of the reception of a CONN_IND. */ /*************************************************************************************************/ @@ -219,11 +204,15 @@ void lctrAdvActSelfTerm(void) WsfMsgFree(pMsg); } - /* Reuse message. */ - lctrMsgHdr_t *pResMsg = (lctrMsgHdr_t *)pBuf - 1; - pResMsg->dispId = LCTR_DISP_ADV; - pResMsg->event = LCTR_ADV_MSG_INT_START; - WsfMsgSend(lmgrPersistCb.handlerId, pResMsg); + /* Cannot reuse pBuf message. */ + lctrMsgHdr_t *pResMsg = WsfMsgAlloc(sizeof(lctrMsgHdr_t)); + + if (pResMsg) + { + pResMsg->dispId = LCTR_DISP_ADV; + pResMsg->event = LCTR_ADV_MSG_INT_START; + WsfMsgSend(lmgrPersistCb.handlerId, pResMsg); + } BbStop(BB_PROT_BLE); } @@ -235,7 +224,7 @@ void lctrAdvActSelfTerm(void) pMsg->hdr.dispId = LCTR_DISP_CONN_IND; /* pMsg->hdr.event = 0; */ - pMsg->connIndEndTs = lctrSlvAdv.reqEndTs; + pMsg->connIndEndTsUsec = lctrSlvAdv.reqEndTsUsec; BbBlePduFiltResultsGetPeerIdAddr(&pAdv->filtResults, &pMsg->peerIdAddr, &pMsg->peerIdAddrType); BbBlePduFiltResultsGetPeerRpa(&pAdv->filtResults, &pMsg->peerRpa); @@ -250,8 +239,6 @@ void lctrAdvActSelfTerm(void) WsfMsgSend(lmgrPersistCb.handlerId, pMsg); } - - WsfMsgFree((lctrMsgHdr_t *)pBuf - 1); } } } @@ -278,8 +265,6 @@ void lctrAdvActSelfTerm(void) /*************************************************************************************************/ /*! * \brief Terminated advertising after host advertising disable. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActAdvTerm(void) @@ -295,8 +280,6 @@ void lctrAdvActAdvTerm(void) /*************************************************************************************************/ /*! * \brief Terminated advertising after host reset. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActResetTerm(void) @@ -309,8 +292,6 @@ void lctrAdvActResetTerm(void) /*************************************************************************************************/ /*! * \brief Update advertising parameters. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvActUpdateAdvParam(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave_ae.c index 13351e79704..d05fe958b17 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave extended advertising action routines. + * \file + * + * \brief Link layer controller slave extended advertising action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,28 +36,11 @@ #include -/*************************************************************************************************/ -/*! - * \brief Disable and clean a generic acad parameter - * - * \param pAcadParam Generic acad parameter type - * - * \return None. - */ -/*************************************************************************************************/ -static void lctrSlvAcadDisable(lctrAcadParam_t *pAcadParam) -{ - memset(pAcadParam, 0, sizeof(*pAcadParam)); - pAcadParam->hdr.state = LCTR_ACAD_STATE_DISABLED; -} - /*************************************************************************************************/ /*! * \brief Common advertise resource cleanup. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ static void lctrExtAdvCleanup(lctrAdvSet_t *pAdvSet) @@ -94,8 +78,6 @@ static void lctrExtAdvCleanup(lctrAdvSet_t *pAdvSet) * \brief Common periodic advertising cleanup. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ static void lctrPeriodicAdvACleanup(lctrAdvSet_t *pAdvSet) @@ -111,8 +93,6 @@ static void lctrPeriodicAdvACleanup(lctrAdvSet_t *pAdvSet) * \brief Start extended advertising. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActStart(lctrAdvSet_t *pAdvSet) @@ -131,7 +111,7 @@ void lctrExtAdvActStart(lctrAdvSet_t *pAdvSet) uint8_t status; if ((status = lctrSlvExtAdvBuildOp(pAdvSet, pLctrSlvExtAdvMsg->enable.durMs)) != LL_SUCCESS) { - // TODO suppress terminate event on failed start + /* TODO suppress terminate event on failed start */ LmgrSendExtAdvEnableCnf(pAdvSet->handle, status); lctrSendAdvSetMsg(pAdvSet, LCTR_EXT_ADV_MSG_TERMINATE); return; @@ -157,8 +137,6 @@ void lctrExtAdvActStart(lctrAdvSet_t *pAdvSet) * \brief Start extended advertising internally. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActSelfStart(lctrAdvSet_t *pAdvSet) @@ -177,7 +155,7 @@ void lctrExtAdvActSelfStart(lctrAdvSet_t *pAdvSet) uint8_t status; if ((status = lctrSlvExtAdvBuildOp(pAdvSet, pLctrSlvExtAdvMsg->enable.durMs)) != LL_SUCCESS) { - // TODO suppress terminate event on failed start + /* TODO suppress terminate event on failed start */ LmgrSendExtAdvEnableCnf(pAdvSet->handle, status); lctrSendAdvSetMsg(pAdvSet, LCTR_EXT_ADV_MSG_TERMINATE); return; @@ -194,8 +172,6 @@ void lctrExtAdvActSelfStart(lctrAdvSet_t *pAdvSet) * \brief Restart extended advertising. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActRestart(lctrAdvSet_t *pAdvSet) @@ -218,8 +194,6 @@ void lctrExtAdvActRestart(lctrAdvSet_t *pAdvSet) * \brief Shutdown active advertising operation. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActShutdown(lctrAdvSet_t *pAdvSet) @@ -239,8 +213,6 @@ void lctrExtAdvActShutdown(lctrAdvSet_t *pAdvSet) * \brief Shutdown active advertising operation due to host reset. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActResetShutdown(lctrAdvSet_t *pAdvSet) @@ -262,8 +234,6 @@ void lctrExtAdvActResetShutdown(lctrAdvSet_t *pAdvSet) * \brief Send advertising operation confirm. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActAdvCnf(lctrAdvSet_t *pAdvSet) @@ -276,8 +246,6 @@ void lctrExtAdvActAdvCnf(lctrAdvSet_t *pAdvSet) * \brief Send advertising operation command disallowed. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet) @@ -291,8 +259,6 @@ void lctrExtAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet) * * \param pAdvSet Advertising set. * - * \return None. - * * Slave self-termination is a result of the expiration of the duration timer, numEvents reached, * or reception of an AUX_CONN_REQ. */ @@ -396,7 +362,7 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet) pMsg->phy = pAdvSet->auxBleData.chan.rxPhy; /* Same PHY as received CONN_IND. */ } - pMsg->connIndEndTs = pAdvSet->connIndEndTs; + pMsg->connIndEndTsUsec = pAdvSet->connIndEndTsUsec; pMsg->localRpa = lmgrSlvAdvCb.localRpa; pMsg->usedChSel = pAdvSet->usedChSel; @@ -439,8 +405,6 @@ void lctrExtAdvActSelfTerm(lctrAdvSet_t *pAdvSet) * \brief Terminated advertising after host advertising disable. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActAdvTerm(lctrAdvSet_t *pAdvSet) @@ -456,8 +420,6 @@ void lctrExtAdvActAdvTerm(lctrAdvSet_t *pAdvSet) * \brief Cleanup Advertising Set after host reset. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActReset(lctrAdvSet_t *pAdvSet) @@ -481,8 +443,6 @@ void lctrExtAdvActReset(lctrAdvSet_t *pAdvSet) * \brief Terminated advertising and cleanup Advertising Set after host reset. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActResetTerm(lctrAdvSet_t *pAdvSet) @@ -500,8 +460,6 @@ void lctrExtAdvActResetTerm(lctrAdvSet_t *pAdvSet) * \brief Advertising set duration timer expired. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrExtAdvActDurationExpired(lctrAdvSet_t *pAdvSet) @@ -517,8 +475,6 @@ void lctrExtAdvActDurationExpired(lctrAdvSet_t *pAdvSet) * \brief Build channel remapping table. * * \param pChanParam Channel parameters. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicBuildRemapTable(lmgrChanParam_t *pChanParam) @@ -544,8 +500,6 @@ void lctrPeriodicBuildRemapTable(lmgrChanParam_t *pChanParam) * \brief Start periodic advertising. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActStart(lctrAdvSet_t *pAdvSet) @@ -596,14 +550,12 @@ void lctrPeriodicAdvActStart(lctrAdvSet_t *pAdvSet) * \brief Restart periodic advertising. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActUpdate(lctrAdvSet_t *pAdvSet) { LmgrSendPeriodicAdvEnableCnf(pAdvSet->handle, LL_SUCCESS); - // TODO cause random address to change + /* TODO cause random address to change */ } /*************************************************************************************************/ @@ -611,8 +563,6 @@ void lctrPeriodicAdvActUpdate(lctrAdvSet_t *pAdvSet) * \brief Send periodic advertising operation confirm. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActAdvCnf(lctrAdvSet_t *pAdvSet) @@ -625,8 +575,6 @@ void lctrPeriodicAdvActAdvCnf(lctrAdvSet_t *pAdvSet) * \brief Send periodic advertising operation command disallowed. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet) @@ -639,8 +587,6 @@ void lctrPeriodicAdvActDisallowAdvCnf(lctrAdvSet_t *pAdvSet) * \brief Shutdown active periodic advertising operation. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActShutdown(lctrAdvSet_t *pAdvSet) @@ -666,8 +612,6 @@ void lctrPeriodicAdvActShutdown(lctrAdvSet_t *pAdvSet) * \brief Terminated advertising after host periodic advertising disable. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet) @@ -682,8 +626,6 @@ void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet) * \brief Terminated periodc advertising after host reset. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrPeriodicAdvActResetTerm(lctrAdvSet_t *pAdvSet) @@ -693,16 +635,14 @@ void lctrPeriodicAdvActResetTerm(lctrAdvSet_t *pAdvSet) /*************************************************************************************************/ /*! - * \brief Acad channel map start handler + * \brief ACAD channel map start handler * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAcadActChanMapUpdateStart(lctrAdvSet_t *pAdvSet) { - lctrAcadChanMapUpd_t *pAcadParam = &pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE].chanMapUpdate; + LctrAcadChanMapUpd_t *pAcadParam = &pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE].chanMapUpdate; /* A new channel map update cannot replace a currently running one. */ if (pAcadParam->hdr.state == LCTR_ACAD_STATE_ENABLED) @@ -710,22 +650,65 @@ void lctrSlvAcadActChanMapUpdateStart(lctrAdvSet_t *pAdvSet) return; } + pAdvSet->perParam.updChanMask = pLctrAcadSlvMsg->chanMapUpd.chanMap; + pAcadParam->chanMask = pAdvSet->perParam.updChanMask; pAcadParam->instant = pAdvSet->perParam.perEventCounter + LL_MIN_INSTANT; - pAcadParam->hdr.len = LL_ACAD_UPDATE_CHANNEL_MAP_LEN; + pAcadParam->hdr.len = LL_ACAD_CHAN_MAP_UPD_LEN; pAcadParam->hdr.state = LCTR_ACAD_STATE_ENABLED; } /*************************************************************************************************/ /*! - * \brief Acad channel map finish handler + * \brief ACAD channel map finish handler * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAcadActChanMapUpdateFinish(lctrAdvSet_t *pAdvSet) { lctrSlvAcadDisable(&pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE]); } + +/*************************************************************************************************/ +/*! + * \brief ACAD BIG created handler + * + * \param pAdvSet Advertising set. + */ +/*************************************************************************************************/ +void lctrSlvAcadActBigCreated(lctrAdvSet_t *pAdvSet) +{ + if (pAdvSet->bigCreated) + { + pAdvSet->bigCreated(pAdvSet->handle); + } +} + +/*************************************************************************************************/ +/*! + * \brief ACAD BIG terminated handler + * + * \param pAdvSet Advertising set. + */ +/*************************************************************************************************/ +void lctrSlvAcadActBigTerminated(lctrAdvSet_t *pAdvSet) +{ + if (pAdvSet->bigTerminated) + { + pAdvSet->bigTerminated(pAdvSet->handle); + } +} + +/*************************************************************************************************/ +/*! + * \brief Disable and clean a generic ACAD parameter + * + * \param pAcadParam Generic ACAD parameter type + */ +/*************************************************************************************************/ +void lctrSlvAcadDisable(lctrAcadParam_t *pAcadParam) +{ + memset(pAcadParam, 0, sizeof(*pAcadParam)); + pAcadParam->hdr.state = LCTR_ACAD_STATE_DISABLED; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_master.c new file mode 100644 index 00000000000..301aed27cdd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_master.c @@ -0,0 +1,271 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller master BIG action routines. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_master.h" +#include "sch_api.h" + +/*************************************************************************************************/ +/*! + * \brief Notify host with BIG Create Sync Complete event + * + * \param pBigCtx BIG context. + * \param status Status. + */ +/*************************************************************************************************/ +static void lctrNotifyHostBigCreateSyncComplete(lctrBigCtx_t *pBigCtx, LlStatus_t status) +{ + LlBigSyncEstInd_t evt = { 0 }; + + evt.hdr.param = pBigCtx->handle; + evt.hdr.event = LL_BIG_SYNC_EST_IND; + evt.hdr.status = status; + + evt.status = status; + evt.bigHandle = pBigCtx->handle; + + if (evt.status == LL_SUCCESS) + { + evt.transLatUsec = pBigCtx->transLatUsec; + evt.nse = pBigCtx->nse; + evt.bn = pBigCtx->bn; + evt.pto = pBigCtx->pto; + evt.irc = pBigCtx->irc; + evt.maxPdu = pBigCtx->maxPdu; + evt.isoInterval = LL_MATH_DIV_1250(pBigCtx->isoInterUsec); + evt.numBis = pBigCtx->numBis; + + for (unsigned int i = 0; i < evt.numBis; i++) + { + evt.bisHandle[i] = pBigCtx->pBisCtx[i]->handle; + } + } + + LL_TRACE_INFO2("### LlEvent ### LL_BIG_SYNC_EST_IND, bigHandle=%u, status=%u", pBigCtx->handle, status); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host with BIG Terminate Sync Complete event + * + * \param bigHandle BIG handle. + * \param status Status. + */ +/*************************************************************************************************/ +void lctrNotifyHostBigTerminateComplete(LlStatus_t status, uint8_t bigHandle) +{ + LlBigTermSyncCnf_t evt; + + /* Clear not required; all values are written. */ + /* memset(&evt, 0, sizeof(LlBigTermSyncCnf_t)); */ + + evt.hdr.param = bigHandle; + evt.hdr.event = LL_BIG_TERM_SYNC_CNF; + evt.hdr.status = status; + + evt.status = status; + evt.bigHandle = bigHandle; + + LL_TRACE_INFO2("### LlEvent ### LL_BIG_TERM_SYNC_CNF, status=%u, bigHandle=%u", status, bigHandle); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host with BIG Terminate Sync Complete event + * + * \param bigHandle BIG handle. + * \param reason Status. + */ +/*************************************************************************************************/ +void lctrNotifyHostSyncLost(uint8_t bigHandle, LlStatus_t reason) +{ + LlBigSyncLostInd_t evt; + + /* Clear not required; all values are written. */ + /* memset(&evt, 0, sizeof(LlBigTermSyncCnf_t)); */ + + evt.hdr.param = bigHandle; + evt.hdr.event = LL_BIG_SYNC_LOST_IND; + evt.hdr.status = LL_SUCCESS; + + evt.bigHandle = bigHandle; + evt.reason = reason; + + LL_TRACE_INFO2("### LlEvent ### LL_BIG_SYNC_LOST_IND, bigHandle=%u, reason=%u", bigHandle, reason); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Start BIG Synchronization. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActStart(lctrBigCtx_t *pBigCtx) +{ + /* Defer until BIG Info received. */ + /* lctrMstBigBuildOp(pBigCtx); */ + + BbStart(BB_PROT_BLE); + + LmgrIncResetRefCount(); +} + +/*************************************************************************************************/ +/*! + * \brief Synchronize to BIG. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActBigSync(lctrBigCtx_t *pBigCtx) +{ + LctrAcadBigInfo_t *pBigInfo = &pLctrMstBigMsg->bigInfo.data; + + lctrMstSetupBigContext(pBigCtx, pBigInfo); + lctrMstSetupBigChannel(pBigCtx, pBigInfo); + + for (unsigned int i = 0; i < pBigInfo->numBis; i++) + { + lctrBisCtx_t *pBisCtx; + + /* Availability is verified on BIG Create Sync command. */ + pBisCtx = lctrAllocBisCtx(pBigCtx); + WSF_ASSERT(pBisCtx); + + lctrSetupBisContext(pBisCtx, pBigInfo->seedAccAddr, pBigInfo->baseCrcInit, pBigInfo->chanMap, pBigInfo->phy); + } + + lctrMstBigBuildOp(pBigCtx, &pLctrMstBigMsg->bigInfo.data); + + WsfTimerStartMs(&pBigCtx->roleData.mst.bigSyncTmr, pBigCtx->roleData.mst.bigSyncTimeoutMs); + + lctrNotifyHostBigCreateSyncComplete(pBigCtx, LL_SUCCESS); +} + +/*************************************************************************************************/ +/*! + * \brief Sync Lost due to BIG Terminated PDU received. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActTerm(lctrBigCtx_t *pBigCtx) +{ + BbStop(BB_PROT_BLE); + + lctrFreeBigCtx(pBigCtx); + + LmgrDecResetRefCount(); + + lctrNotifyHostSyncLost(pBigCtx->handle, pBigCtx->bcp.term.reason); +} + +/*************************************************************************************************/ +/*! + * \brief Shutdown active BIS operation. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActShutdown(lctrBigCtx_t *pBigCtx) +{ + /* By removing BOD from scheduler, BOD end callback will be called. */ + /* Shutdown completes with events generated in BOD end callback. */ + if (!SchRemove(&pBigCtx->bod)) + { + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_TERMINATED_SYNC); + } + + if (pBigCtx->state == LCTR_MST_BIG_STATE_SYNCING) + { + lctrNotifyHostBigCreateSyncComplete(pBigCtx, LL_ERROR_CODE_CONN_TERM_BY_LOCAL_HOST); + } +} + +/*************************************************************************************************/ +/*! + * \brief Synchronization with broadcaster lost. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActSyncLost(lctrBigCtx_t *pBigCtx) +{ + /* By removing BOD from scheduler, BOD end callback will be called. */ + /* Shutdown completes with events generated in BOD end callback. */ + if (!SchRemove(&pBigCtx->bod)) + { + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_TERMINATED_SYNC); + } + + pBigCtx->roleData.mst.syncLostReason = LL_ERROR_CODE_CONN_TIMEOUT; +} + +/*************************************************************************************************/ +/*! + * \brief Drop synchronization due to MIC failure. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActMicFailed(lctrBigCtx_t *pBigCtx) +{ + /* By removing BOD from scheduler, BOD end callback will be called. */ + /* Shutdown completes with events generated in BOD end callback. */ + if (!SchRemove(&pBigCtx->bod)) + { + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_TERMINATED_SYNC); + } + + pBigCtx->roleData.mst.syncLostReason = LL_ERROR_CODE_CONN_TERM_MIC_FAILURE; +} + +/*************************************************************************************************/ +/*! + * \brief Terminated advertising after host periodic advertising disable. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrMstBigActCleanup(lctrBigCtx_t *pBigCtx) +{ + BbStop(BB_PROT_BLE); + + lctrFreeBigCtx(pBigCtx); + + LmgrDecResetRefCount(); + + if (pBigCtx->roleData.mst.syncLostReason != LL_SUCCESS) + { + lctrNotifyHostSyncLost(pBigCtx->handle, pBigCtx->roleData.mst.syncLostReason); + } + else + { + lctrNotifyHostBigTerminateComplete(LL_SUCCESS, pBigCtx->handle); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_slave.c new file mode 100644 index 00000000000..d6498a04f50 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_bis_slave.c @@ -0,0 +1,211 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller slave BIG action routines. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_slave.h" +#include "lctr_int_iso.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Start BIS slave advertising. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSlvBigActStart(lctrBigCtx_t *pBigCtx) +{ + uint8_t status; + + if ((status = lctrSlvBigBuildOp(pBigCtx)) != LL_SUCCESS) + { + lctrSlvBigSendMsg(pBigCtx, LCTR_SLV_BIG_MSG_TERMINATED); + lctrNotifyHostCreateBigComplete(pBigCtx, status); + return; + } + + BbStart(BB_PROT_BLE); + + lctrAdvSet_t * const pAdvSet = pBigCtx->roleData.slv.pAdvSet; + + if (pAdvSet) + { + pAdvSet->perParam.perAdvEnabled = TRUE; + + /* Add SyncInfo to the Extended Advertising. */ + if (pAdvSet->state == LCTR_EXT_ADV_STATE_ENABLED) + { + if ((pAdvSet->auxBodUsed == FALSE)) + { + pAdvSet->perParam.perAuxStart = TRUE; + } + + /* The Advertising DID is required to change when a SyncInfo field is added to or removed. */ + pAdvSet->advData.alt.ext.did = lctrCalcDID(pAdvSet->advData.pBuf, pAdvSet->advData.len); + pAdvSet->didPerUpdate = TRUE; + } + } + + lctrSlvBigSendAcadMsg(pBigCtx, LCTR_ACAD_MSG_BIG_CREATED); + + LmgrIncResetRefCount(); +} + +/*************************************************************************************************/ +/*! + * \brief Broadcast channel map updates. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSlvBigActSendChMapUpd(lctrBigCtx_t *pBigCtx) +{ + if (pBigCtx->bcp.actMsk) + { + LL_TRACE_INFO1("BIG Control Procedure in progress; pend BIG Channel Map Update, bigHandle=%u", pBigCtx->handle); + pBigCtx->bcp.pendMsk |= 1 << LL_BIG_OPCODE_CHAN_MAP_IND; + return; + } + + uint8_t *pPdu; + + if ((pPdu = lctrBigTxCtrlAlloc(LL_BIG_CHAN_MAP_IND_PDU_LEN)) != NULL) + { + uint16_t inst = pBigCtx->eventCounter + LL_BIG_MIN_INSTANT; + + uint8_t *pBuf = pPdu; + + lctrBisDataPduHdr_t hdr = + { + .llid = LL_LLID_BIG_CTRL_PDU, + .cssn = 0, /* Completed in ISR. */ + .cstf = 0, /* Always 0. */ + .len = LL_BIG_OPCODE_LEN + LL_BIG_CHAN_MAP_IND_PDU_LEN + }; + + pBuf += lctrBisPackDataPduHdr(pBuf, &hdr); + lctrBisPackBigChannelMapInd(pBuf, lmgrCb.chanClass, inst); + + lctrBigTxCtrlQueue(pBigCtx, pPdu, LL_MIN_INSTANT); + + pBigCtx->bcp.actMsk |= 1 << LL_BIG_OPCODE_CHAN_MAP_IND; + pBigCtx->bcp.chanMapUpd.chanMap = lmgrCb.chanClass; + pBigCtx->bcp.chanMapUpd.inst = inst; + + LL_TRACE_INFO2("BIG Channel Map Procedure, bigHandle=%u, instant=%u", pBigCtx->handle, inst); + + if (pBigCtx->roleData.slv.pAdvSet) + { + /* Temporarily disable BIG Info transmissions. */ + LctrAcadBigInfo_t *pBigInfo = &pBigCtx->roleData.slv.pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + pBigInfo->hdr.state = LCTR_ACAD_STATE_DISABLED; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Broadcast terminate. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSlvBigActSendTerm(lctrBigCtx_t *pBigCtx) +{ + if (pBigCtx->bcp.actMsk) + { + LL_TRACE_INFO1("BIG Control Procedure in progress; pend BIG Terminate, bigHandle=%u", pBigCtx->handle); + pBigCtx->bcp.pendMsk |= 1 << LL_BIG_OPCODE_BIG_TERM_IND; + return; + } + + uint8_t *pBuf; + + if ((pBuf = lctrBigTxCtrlAlloc(LL_BIG_TERMINATE_IND_PDU_LEN)) != NULL) + { + uint16_t inst = pBigCtx->eventCounter + LL_BIG_MIN_INSTANT; + + uint8_t *pPdu = pBuf; + + lctrBisDataPduHdr_t hdr = + { + .llid = LL_LLID_BIG_CTRL_PDU, + .cssn = 0, /* Completed in ISR. */ + .cstf = 0, /* Always 0. */ + .len = LL_BIG_OPCODE_LEN + LL_BIG_TERMINATE_IND_PDU_LEN + }; + + pBuf += lctrBisPackDataPduHdr(pBuf, &hdr); + lctrBisPackBigTerminateInd(pBuf, pBigCtx->bcp.term.reason, inst); + + lctrBigTxCtrlQueue(pBigCtx, pPdu, LL_BIG_MIN_INSTANT); + + pBigCtx->bcp.actMsk |= 1 << LL_BIG_OPCODE_BIG_TERM_IND; + pBigCtx->bcp.term.inst = inst; + + LL_TRACE_INFO2("BIG Terminate Procedure, bigHandle=%u, instant=%u", pBigCtx->handle, inst); + } + + lctrSlvBigSendAcadMsg(pBigCtx, LCTR_ACAD_MSG_BIG_TERMINATED); +} + +/*************************************************************************************************/ +/*! + * \brief Shutdown active BIS operation. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSlvBigActShutdown(lctrBigCtx_t *pBigCtx) +{ + /* By removing BOD from scheduler, BOD end callback will be called. */ + /* Shutdown completes with events generated in BOD end callback. */ + SchRemove(&pBigCtx->bod); + + lctrSlvBigSendAcadMsg(pBigCtx, LCTR_ACAD_MSG_BIG_TERMINATED); +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup BIG contexts. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSlvBigActCleanup(lctrBigCtx_t *pBigCtx) +{ + lctrNotifyHostTerminateBigComplete(pBigCtx); + + SchRmRemove(LCTR_BIG_TO_RM_HANDLE(pBigCtx)); + + lctrFreeBigCtx(pBigCtx); + + BbStop(BB_PROT_BLE); + + LmgrDecResetRefCount(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis.c new file mode 100644 index 00000000000..b333ca26d26 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis.c @@ -0,0 +1,538 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller master connected isochronous stream state machine action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis.h" +#include "lctr_int_iso.h" +#include "lmgr_api_cis_master.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "wsf_trace.h" +#include "wsf_assert.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Send CIS termination indication PDU. + * + * \param pCtx Connection context. + * \param opcode Pdu Opcode. + * \param pCisCtx CIS context. + * \param reason Termination reason. + */ +/*************************************************************************************************/ +static void lctrSendCisTermIndPdu(lctrConnCtx_t *pCtx, uint8_t opcode, lctrCisCtx_t *pCisCtx, uint8_t reason) +{ + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_CIS_TERM_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + + /*** Assemble control PDU. ***/ + UINT8_TO_BSTREAM (pBuf, opcode); + UINT8_TO_BSTREAM (pBuf, pCisCtx->cigId); + UINT8_TO_BSTREAM (pBuf, pCisCtx->cisId); + UINT8_TO_BSTREAM (pBuf, reason); + + /*** Queue for transmit. ***/ + lctrTxCtrlPduQueue(pCtx, pPdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send CIS termination indication. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + * \param reason Termination reason. + */ +/*************************************************************************************************/ +static void lctrSendCisTermInd(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t reason) +{ + lctrSendCisTermIndPdu(pCtx, LL_PDU_CIS_TERM_IND, pCisCtx, reason); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Notify host of CIS disconnected event + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrNotifyHostCisTerm(lctrCisCtx_t *pCisCtx) +{ + LlDisconnectInd_t evt = + { + .hdr = + { + .param = pCisCtx->cisHandle, + .event = LL_DISCONNECT_IND, + .status = LL_SUCCESS + }, + + .status = LL_SUCCESS, + .handle = pCisCtx->cisHandle, + .reason = pCisCtx->reason + }; + + LL_TRACE_INFO2("### LlEvent ### LL_DISCONNECT_IND, handle=%u, status=LL_SUCCESS, reason=%u", pCisCtx->cisHandle, pCisCtx->reason); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of CIS established event + * + * \param pCisCtx CIS context. + * \param status Status. + * \param cigSyncDelayUsec CIG synchronization delayn in usec. + */ +/*************************************************************************************************/ +void lctrNotifyHostCisEst(lctrCisCtx_t *pCisCtx, uint8_t status, uint32_t cigSyncDelayUsec) +{ + LlCisEstInd_t evt = + { + .hdr = + { + .param = pCisCtx->cisHandle, + .event = LL_CIS_EST_IND, + .status = status + } + }; + + evt.cisHandle = pCisCtx->cisHandle; + evt.status = status; + evt.cigSyncDelayUsec = cigSyncDelayUsec; + evt.cisSyncDelayUsec = pCisCtx->cisSyncDelayUsec; + evt.transLatUsecMToS = pCisCtx->transLatUsec; /* For now it is 0, update it when ISOAL is supported. */ + evt.transLatUsecSToM = pCisCtx->transLatUsec; /* For now it is 0, update it when ISOAL is supported. */ + evt.phyMToS = pCisCtx->phyMToS; + evt.phySToM = pCisCtx->phySToM; + evt.nse = pCisCtx->nse; + evt.bnMToS = pCisCtx->bnMToS; + evt.bnSToM = pCisCtx->bnSToM; + evt.ftMToS = pCisCtx->ftMToS; + evt.ftSToM = pCisCtx->ftSToM; + evt.isoInterval = pCisCtx->isoInterval; + + LL_TRACE_INFO2("### LlEvent ### LL_CIS_EST_IND, cisHandle=%u, status=%u", pCisCtx->cisHandle, status); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Send internal CIS subsystem message. + * + * \param pCisCtx CIS context. + * \param event CIS event. + */ +/*************************************************************************************************/ +void lctrSendCisMsg(lctrCisCtx_t *pCisCtx, uint8_t event) +{ + lctrMsgHdr_t *pMsg; + + if ((pMsg = (lctrMsgHdr_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pCisCtx->cisHandle; + pMsg->dispId = LCTR_DISP_CIS; + pMsg->event = event; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send internal CIS LLCP subsystem message. + * + * \param pCisCtx CIS context. + * \param event Connection event. + */ +/*************************************************************************************************/ +void lctrSendCisLlcpMsg(lctrCisCtx_t *pCisCtx, uint8_t event) +{ + lctrMsgHdr_t *pMsg; + + if ((pMsg = (lctrMsgHdr_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pCisCtx->aclHandle; + pMsg->dispId = LCTR_DISP_CONN; + pMsg->event = event; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Store LLCP termination reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = lctrDataPdu.pld.cisTerm.reason; +} + +/*************************************************************************************************/ +/*! + * \brief Store host initiated disconnect termination reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreDisconnectReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = pLctrCisMsg->disc.reason; +} + +/*************************************************************************************************/ +/*! + * \brief Store connection failed to establish termination reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreConnFailEstablishTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH; +} + +/*************************************************************************************************/ +/*! + * \brief Store connection timeout termination reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreConnTimeoutTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = LL_ERROR_CODE_CONN_TIMEOUT; +} + +/*************************************************************************************************/ +/*! + * \brief Store LLCP timeout termination reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreLlcpTimeoutTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = LL_ERROR_CODE_LMP_LL_RESP_TIMEOUT; +} + +/*************************************************************************************************/ +/*! + * \brief Store local resource limitation reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreLocalLowResourceTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; +} + +/*************************************************************************************************/ +/*! + * \brief Store LLCP peer reject reason. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStoreLlcpPeerRejTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = lctrDataPdu.pld.rejInd.reason; +} + +/*************************************************************************************************/ +/*! + * \brief Store invalid request termination reason. + * + * \param pCisCtx CIS connection context. + */ +/*************************************************************************************************/ +void lctrCisStoreMicFailedTerminateReason(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = LL_ERROR_CODE_CONN_TERM_MIC_FAILURE; +} + +/************************************************************************************************** + CIS main state machine action functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Action function for CIS established. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisActCisEst(lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + BbBleData_t *pBle = &pConnCtx->bleData; + pCigCtx->numCisEsted++; + + LL_TRACE_INFO1("lctrCisActCisEst, pCigCtx->numCisEsted=%u", pCigCtx->numCisEsted); + + /* Initialize txPower. */ + uint8_t txPhy = (pCisCtx->role == LL_ROLE_MASTER) ? pCisCtx->phyMToS : pCisCtx->phySToM; + uint8_t option = pBle->chan.initTxPhyOptions; + int8_t txPwr = LCTR_GET_TXPOWER(pConnCtx, txPhy, option); + LL_TRACE_INFO1("lctrCisActCisEst phy = %d", txPhy); + + if ((txPwr == LL_PWR_CTRL_TXPOWER_UNMANAGED) && (pConnCtx->peerReqRecvd)) + { + LL_TRACE_INFO0(" txPower previously unmanaged. Initalized txPower."); + + LCTR_SET_TXPOWER(pConnCtx, txPhy, pLctrRtCfg->defTxPwrLvl); + + if (txPhy == LL_PHY_LE_CODED) + { + LCTR_SET_TXPOWER(pConnCtx, LL_PC_PHY_CODED_S2, pLctrRtCfg->defTxPwrLvl); + } + + /* pCisCtx->bleData.chan.txPower = LCTR_GET_TXPOWER(pConnCtx, txPhy, option); //Handled in the init */ + if (pConnCtx->usedFeatSet & LL_FEAT_POWER_CHANGE_IND) + { + pCisCtx->powerIndReq = TRUE; + } + } + else + { + LL_TRACE_INFO1(" txPower = %d", txPwr); + pCisCtx->bleData.chan.txPower = txPwr; + } + +} + +/*************************************************************************************************/ +/*! + * \brief Action function for CIS fail to establish. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisActCisEstFail(lctrCisCtx_t *pCisCtx) +{ + /* LLCP timeout for the LL_CIS_REQ indicates peer doesn't support CIS feature. */ + if (pCisCtx->isCisReqPend && + pCisCtx->reason == LL_ERROR_CODE_LMP_LL_RESP_TIMEOUT) + { + pCisCtx->isCisReqPend = FALSE; + lctrNotifyHostCisEst(pCisCtx, LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE, 0 /* cigSyncDelayUsec */); + return; + } + + lctrNotifyHostCisEst(pCisCtx, pCisCtx->reason, 0 /* cigSyncDelayUsec */); + + lctrCleanupCtx(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received host disconnect CIS. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisActDisc(lctrCisCtx_t *pCisCtx) +{ + lctrCisDisc_t *pMsg; + + if ((pMsg = (lctrCisDisc_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = pCisCtx->aclHandle; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_DISCONNECT; + + pMsg->cisHandle = pCisCtx->cisHandle; + pMsg->reason = pCisCtx->reason; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received internal CIS closed. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisActClosed(lctrCisCtx_t *pCisCtx) +{ + /* Stop output data path. */ + switch (pCisCtx->dataPathOutCtx.id) + { + case LL_ISO_DATA_PATH_VS: + WSF_ASSERT(lctrCodecHdlr.stop); + lctrCodecHdlr.stop(pCisCtx->cisHandle); + break; + case LL_ISO_DATA_PATH_DISABLED: + case LL_ISO_DATA_PATH_HCI: + default: + /* No action required. */ + break; + } + + LL_TRACE_INFO1("lctrCisActClosed, pCisCtx->cisHandle=%u", pCisCtx->cisHandle); + + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + WSF_ASSERT(pCigCtx); + WSF_ASSERT(pConnCtx); + + WsfTimerStop(&pCisCtx->tmrSupTimeout); + + pCisCtx->isClosing = TRUE; /* Close the context in the CIG BOD end callback. */ + + /* Fast supervision timeout case. */ + if (pCisCtx->isClosing == TRUE && + pCisCtx->reason == LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH) + { + pCisCtx->isClosing = FALSE; + lctrCleanupCtx(pCisCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received internal CIS connection fail to maintain event. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisActFail(lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + LL_TRACE_INFO2("lctrCisActFail, pCisCtx->cisHandle=%u pCisCtx->state=%u", pCisCtx->cisHandle, pCisCtx->state); + + /* Supervision timeout case */ + if (pCisCtx->state == LCTR_CIS_STATE_EST) + { + pCisCtx->isClosing = TRUE; /* Close the context in the CIG BOD end callback. */ + SchRemove(&pCigCtx->cigBod); + lctrNotifyHostCisTerm(pCisCtx); + } +} + +/************************************************************************************************** + CIS LLCP state machine action functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Action function for LLCP received host disconnect. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisLlcpActHostDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + lctrSendCisTermInd(pCtx, pCisCtx, pCisCtx->reason); + lctrCisStartLlcpTimer(pCtx, pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for LLCP received CIS peer disconnect. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisLlcpActPeerDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + lctrCisStoreTerminateReason(pCisCtx); + + pCtx->termAckReqd = TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Action function for LLCP received CIS terminated event. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisLlcpActCisTerm(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for LLCP received internal host disconnect. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisLlcpActIntHostDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrSendCisTermInd(pCtx, pCisCtx, pCisCtx->reason); + lctrCisStartLlcpTimer(pCtx, pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for LLCP received internal CIS peer disconnect. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisLlcpActIntPeerDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + pCtx->termAckReqd = TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_master.c new file mode 100644 index 00000000000..71e1e2f3279 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_master.c @@ -0,0 +1,481 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer connected isochronous stream master state machine action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis_master.h" +#include "lctr_api_conn.h" +#include "lctr_api_cis_master.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Calculate the next referenced connection event for the first CIS. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCalCeRefFirstCis(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + BbOpDesc_t *pConnBod = &pCtx->connBod; + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + uint32_t refTime; + + pCisCtx->ceRef = pCtx->eventCounter + + LL_MIN_INSTANT + 1 + /* +1 for next CE */ + pCtx->maxLatency; /* ensure slave will listen to this packet */ + pCisCtx->cisCeRef = 0; + + refTime = pConnBod->dueUsec + (pCisCtx->ceRef - pCtx->eventCounter) * LCTR_CONN_IND_US(pCtx->connInterval); + pCisCtx->offsetUsec = SchRmGetOffsetUsec(LCTR_ISO_INT_TO_US(pCigCtx->isoInterval), + LCTR_GET_CIG_RM_HANDLE(pCigCtx), refTime); + + /* Adjust offset make sure CisOffMaxUsec shall be less than + * (connInterval – ((NSE – 1) × Sub_Interval + MPTM + T_IFS + MPTS + T_MSS)) */ + while (pCisCtx->offsetUsec >= (LCTR_CONN_IND_US(pCtx->connInterval) - (pCisCtx->nse * pCisCtx->subIntervUsec - pLctrRtCfg->cisSubEvtSpaceDelay))) + { + pCisCtx->offsetUsec -= LCTR_CONN_IND_US(pCtx->connInterval); + pCisCtx->ceRef++; + } + +#if (LL_ENABLE_TESTER) + if (llTesterCb.cisRspEnabled) + { + pCisCtx->offsetUsec = llTesterCb.cisOffMinUsec; + pCisCtx->ceRef += llTesterCb.cisCeRef; + + llTesterCb.cisRspEnabled = FALSE; + } +#endif +} + +/*************************************************************************************************/ +/*! + * \brief Calculate the next referenced connection event for CIS after first one. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCalCeRefNotFirstCis(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + BbOpDesc_t *pConnBod = &pCtx->connBod; + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + uint32_t aclRefTime, cigRefTime; + bool_t result = FALSE; + uint32_t offsetUsec = 0; + + pCisCtx->ceRef = pCtx->eventCounter + + LL_MIN_INSTANT + 1 + /* +1 for next CE */ + pCtx->maxLatency; /* ensure slave will listen to this packet */ + + aclRefTime = pConnBod->dueUsec + (pCisCtx->ceRef - pCtx->eventCounter) * LCTR_CONN_IND_US(pCtx->connInterval); + + /* Find the reference event when CIS shall be transfered. */ + pCisCtx->cisCeRef = 0; + + while (result == FALSE) + { + pCisCtx->cisCeRef++; + cigRefTime = pCigCtx->cigBod.dueUsec + pCisCtx->cisCeRef * LCTR_ISO_INT_TO_US(pCigCtx->isoInterval); + + if (BbGetTargetTimeDelta(cigRefTime, aclRefTime) > 0) + { + result = TRUE; + } + } + + pCisCtx->offsetUsec = BbGetTargetTimeDelta(cigRefTime, aclRefTime); + + /* Adjust offset make sure CisOffMaxUsec shall be less than + * (connInterval – ((NSE – 1) × Sub_Interval + MPTM + T_IFS + MPTS + T_MSS)) */ + while (pCisCtx->offsetUsec >= (LCTR_CONN_IND_US(pCtx->connInterval) - (pCisCtx->nse * pCisCtx->subIntervUsec - pLctrRtCfg->cisSubEvtSpaceDelay))) + { + pCisCtx->offsetUsec -= LCTR_CONN_IND_US(pCtx->connInterval); + pCisCtx->ceRef++; + } + + if (pCigCtx->packing == LL_PACKING_SEQUENTIAL) + { + lctrCisNode_t *pTempNode = pCigCtx->list.pHead; + WSF_ASSERT(pTempNode); /* There is at least one CIS in the list. */ + + while (pTempNode) + { + lctrCisCtx_t *pTempCtx = pTempNode->pCisCtx; + + offsetUsec += pTempCtx->subIntervUsec * pTempCtx->nse; + pTempNode = pTempNode->pNext; + } + + } + else if (pCigCtx->packing == LL_PACKING_INTERLEAVED) + { + lctrCisNode_t *pTempNode = pCigCtx->list.pHead; + WSF_ASSERT(pTempNode); /* There is at least one CIS in the list. */ + + while (pTempNode) + { + lctrCisCtx_t *pTempCtx = pTempNode->pCisCtx; + + offsetUsec += pTempCtx->delayUsec; + pTempNode = pTempNode->pNext; + } + } + else + { + LL_TRACE_WARN1("Invalid packing scheme=%d", pCigCtx->packing); + } + + pCisCtx->cisSyncDelayUsec = pCisCtx->cigSyncDelayUsec - offsetUsec; + pCisCtx->offsetUsec += offsetUsec; +} + +/*************************************************************************************************/ +/*! + * \brief Check whether the value in the CIS_RSP is valid or not + * + * \param pCisCtx CIS context. + * + * \return TRUE if valid, otherwise FALSE. + */ +/*************************************************************************************************/ +static bool_t lctrCheckPeerCisRsp(lctrCisCtx_t *pCisCtx) +{ + if (lctrDataPdu.pld.cisRsp.cisOffMaxUsec < lctrDataPdu.pld.cisRsp.cisOffMinUsec) + { + return FALSE; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Send CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + * \param numCis Total number of CIS in CIG. + */ +/*************************************************************************************************/ +static void lctrSendCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t numCis) +{ + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_CIS_REQ_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + + /*** Assemble control PDU ***/ + + UINT8_TO_BSTREAM (pBuf, LL_PDU_CIS_REQ); + UINT8_TO_BSTREAM (pBuf, pCisCtx->cigId); + UINT8_TO_BSTREAM (pBuf, pCisCtx->cisId); + + /* PHY_Info */ + UINT8_TO_BSTREAM (pBuf, lctrPhyToPhysBit(pCisCtx->phyMToS)); + UINT8_TO_BSTREAM (pBuf, lctrPhyToPhysBit(pCisCtx->phySToM)); + + /* SDU_Parameters */ + UINT16_TO_BSTREAM(pBuf, (pCisCtx->sduSizeMToS & 0x0FFF) | + ((pCisCtx->framing & 0x01) << 15)); /* Max_SDU_Size_M_To_S | ISOAL_PDU_Type */ + UINT16_TO_BSTREAM(pBuf, (pCisCtx->sduSizeSToM & 0x0FFF)); /* Max_SDU_Size_S_To_M */ + UINT24_TO_BSTREAM(pBuf, (pCisCtx->sduIntervalMToS & 0xFFFFF)); /* SDU_Interval_M_To_S */ + UINT24_TO_BSTREAM(pBuf, (pCisCtx->sduIntervalSToM & 0xFFFFF)); /* SDU_Interval_M_To_S */ + + /* CIS_Parameters */ + UINT16_TO_BSTREAM(pBuf, pCisCtx->localDataPdu.maxTxLen); + UINT16_TO_BSTREAM(pBuf, pCisCtx->localDataPdu.maxRxLen); + UINT8_TO_BSTREAM (pBuf, pCisCtx->nse); + UINT24_TO_BSTREAM(pBuf, pCisCtx->subIntervUsec); /* Subevent interval */ + UINT8_TO_BSTREAM (pBuf, ((pCisCtx->bnSToM & 0x0F) << 4) | + (pCisCtx->bnMToS & 0x0F)); /* BN_M_To_S */ /* BN_S_To_M */ + UINT8_TO_BSTREAM (pBuf, pCisCtx->ftMToS); + UINT8_TO_BSTREAM (pBuf, pCisCtx->ftSToM); + UINT16_TO_BSTREAM(pBuf, pCisCtx->isoInterval); + + /* CIS_Offset */ + UINT24_TO_BSTREAM(pBuf, pCisCtx->offsetUsec); /* CIS_OFFSET_MIN */ + UINT24_TO_BSTREAM(pBuf, pCisCtx->offsetUsec +#if (LL_ENABLE_TESTER) + + llTesterCb.cisOffMaxUsec +#endif + ); /* CIS_OFFSET_MAX */ + + /* ACL_Conn_Event_Count */ + UINT16_TO_BSTREAM(pBuf, pCisCtx->ceRef); /* Event counter */ + + /*** Queue for transmit ***/ + + lctrTxCtrlPduQueue(pCtx, pPdu); + } + + pCisCtx->isCisReqPend = TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Send CIS indication PDU. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrSendCisInd(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_CIS_IND_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + + /*** Assemble control PDU ***/ + + UINT8_TO_BSTREAM (pBuf, LL_PDU_CIS_IND); + UINT32_TO_BSTREAM(pBuf, pCisCtx->accessAddr); /* Access address */ + UINT24_TO_BSTREAM(pBuf, pCisCtx->offsetUsec); /* CIS offset */ + UINT24_TO_BSTREAM(pBuf, pCisCtx->cigSyncDelayUsec); /* CIG sync delay */ + UINT24_TO_BSTREAM(pBuf, pCisCtx->cisSyncDelayUsec); /* CIS sync delay */ + UINT16_TO_BSTREAM(pBuf, pCisCtx->ceRef); /* CE */ + + /*** Queue for transmit ***/ + + lctrTxCtrlPduQueue(pCtx, pPdu); + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/************************************************************************************************** + CIS master LLCP state machine action functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Action function for received host CIS request command. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisLlcpActHostCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + if (pCigCtx->numCisEsted == 0) + { + bool_t result = TRUE; + + /* Check whether the parameter for the BOD is valid or not. */ + if (pCigCtx->isValid == FALSE) + { + LL_TRACE_WARN0("Fail to create CIS due to invalid parameters"); + lctrCisStoreLocalLowResourceTerminateReason(pCisCtx); + result = FALSE; + } + + /* Check whether the BOD can be scheduled or not. */ + if ((result == TRUE) && (pCigCtx->isRmAdded == FALSE)) + { + if (!SchRmAdd(LCTR_GET_CIG_RM_HANDLE(pCigCtx), + SCH_RM_PREF_PERFORMANCE, + LCTR_ISO_INT_TO_US(pCigCtx->isoInterval), + LCTR_ISO_INT_TO_US(pCigCtx->isoInterval), + pCigCtx->cigSyncDelayUsec, NULL, lctrGetCigRefTime)) + { + LL_TRACE_WARN0("Fail to create CIS due to scheduling limitation"); + lctrCisStoreLocalLowResourceTerminateReason(pCisCtx); + result = FALSE; + } + else + { + pCigCtx->isRmAdded = TRUE; + } + } + + if (!result) + { + lctrMsgHdr_t *pTermMsg; + + /* Send SM a terminate event. */ + if ((pTermMsg = (lctrMsgHdr_t *)WsfMsgAlloc(sizeof(*pTermMsg))) != NULL) + { + pTermMsg->handle = pCisCtx->aclHandle; + pTermMsg->dispId = LCTR_DISP_CONN; + pTermMsg->event = LCTR_CONN_TERM_CIS_LOCAL_RESOURCE; + + WsfMsgSend(lmgrPersistCb.handlerId, pTermMsg); + } + return; + } + + lctrCalCeRefFirstCis(pCtx, pCisCtx); + + lctrCisInsertHead(&pCigCtx->list, pCisCtx); + } + else + { + lctrCalCeRefNotFirstCis(pCtx, pCisCtx); + + lctrCisInsertTail(&pCigCtx->list, pCisCtx); + } + + /* Each ACL may have different check CIS link termination function. */ + pCtx->checkCisTerm = lctrCheckForCisLinkTerm; + pCtx->checkCisEstAcl = lctrCheckIsCisEstAcl; + lctrCheckCisEstCisFn = lctrCheckIsCisEstCis; + + pCisCtx->aclHandle = pLctrConnMsg->createCis.hdr.handle; /* Save ACL handle to the CIS context. */ + /* Update CRCInit and supervision timeout from the ACL the CIS is on. */ + pCisCtx->crcInit = pCtx->crcInit; + pCisCtx->supTimeoutMs = pCtx->supTimeoutMs; + + lctrCisSetupChanParam(pCisCtx, pCtx->chanMask); + + lctrSendCisReq(pCtx, pCisCtx, pCigCtx->roleData.mst.numCis); + lctrCisStartLlcpTimer(pCtx, pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received peer LL_CIS_REJ_EXT command. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisLlcpActPeerRej(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + pCisCtx->isCisReqPend = FALSE; + lctrCisStoreLlcpPeerRejTerminateReason(pCisCtx); + + lctrMstCreateCisDone(pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST_FAIL); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received peer LL_CIS_RSP command. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisLlcpActPeerCisRsp(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + if (lctrCheckPeerCisRsp(pCisCtx) == FALSE) + { + /* CIS establishment fails when values in the CIS_RSP are invalid. */ + lctrSendRejectInd(pCtx, LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES, TRUE); + lctrCisStopLlcpTimer(pCtx, pCisCtx); + + pCisCtx->isCisReqPend = FALSE; + lctrCisStoreLocalLowResourceTerminateReason(pCisCtx); + lctrCisRemove(&pCigCtx->list, pCisCtx); + lctrMstCreateCisDone(pCisCtx); + + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST_FAIL); + return; + } + + if (pCigCtx->isBodBuilt == FALSE) + { + WSF_ASSERT(pCisCtx->cisCeRef == 0) + + lctrMstCisBuildCigOp(pCigCtx); + } + else + { + lctrMstCisBuildCisData(pCisCtx); + } + + lctrCisSetupEncrypt(pCisCtx); + + if (pCigCtx->isBodStarted == FALSE) + { + /* Commit the BOD and calculate the offset. */ + lctrMstCisCigOpCommit(pCigCtx, pCtx, pCisCtx); + } + else + { + /* TODO */ + /* BOD is already committed, calculate the offset. */ + } + + pCisCtx->isCisReqPend = FALSE; + lctrSendCisInd(pCtx, pCisCtx); + lctrCisStopLlcpTimer(pCtx, pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received internal LLCP response timeout. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisLlcpActRspTimeout(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + lctrCisStopLlcpTimer(pCtx, pCisCtx); + lctrCisStoreLlcpTimeoutTerminateReason(pCisCtx); + lctrCisRemove(&pCigCtx->list, pCisCtx); + lctrMstCreateCisDone(pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST_FAIL); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received internal LLCP reject. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisLlcpActLocalReject(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrMstCreateCisDone(pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST_FAIL); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_slave.c new file mode 100644 index 00000000000..133d1ba1d20 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_cis_slave.c @@ -0,0 +1,508 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer connected isochronous stream slave state machine action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis_slave.h" +#include "lhci_api.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "wsf_trace.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Check if CIS request parameters are in range or not. + * + * \param pCtx ACL connection context. + * \param pCisCtx CIS connection context. + * \param pCisReq CIS request parameter. + * + * \return Status error code. + */ +/*************************************************************************************************/ +static uint8_t LctrCheckCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, const lctrCisReq_t *pCisReq) +{ + if ((pCisReq->isoInterval < LL_MIN_ISO_INTERV) || + (pCisReq->isoInterval > LL_MAX_ISO_INTERV) || + (pCisReq->nse > LL_MAX_CIS_NSE) || + (pCisReq->framing > LL_MAX_ISOAL_PDU_TYPE) || + (pCisReq->sduSizeMToS > LL_MAX_SDU_SIZE) || + (pCisReq->sduSizeSToM > LL_MAX_SDU_SIZE) || + (pCisReq->sduIntervalMToS > LL_MAX_SDU_INTERV) || + (pCisReq->sduIntervalSToM > LL_MAX_SDU_INTERV) || + (pCisReq->plMToS > LL_MAX_CIS_PL) || + (pCisReq->plSToM > LL_MAX_CIS_PL) || + (pCisReq->phyMToS > (1 << LL_MAX_CIS_PHY_BIT)) || + (pCisReq->phySToM > (1 << LL_MAX_CIS_PHY_BIT)) || + (pCisReq->ftMToS < LL_MIN_CIS_FT) || + (pCisReq->ftMToS > LL_MAX_CIS_FT) || + (pCisReq->ftSToM < LL_MIN_CIS_FT) || + (pCisReq->ftSToM > LL_MAX_CIS_FT) || + (pCisReq->bnMToS > LL_MAX_CIS_BN) || + (pCisReq->bnSToM > LL_MAX_CIS_BN)) + { + LL_TRACE_WARN0("LctrCheckCisReq: invalid parameters, parameter out of range"); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + /* CisOffMaxUsec shall be greater than or equal to CIS_Offset_Min */ + if (pCisReq->cisOffMaxUsec < pCisReq->cisOffMinUsec) + { + LL_TRACE_WARN0("LctrCheckCisReq: invalid parameters, cisOffMaxUsec shall be greater than cisOffMinUsec"); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + + /* CisOffMaxUsec shall be less than (connInterval – ((NSE – 1) × Sub_Interval + MPTM + T_IFS + MPTS + T_MSS)) */ + if (pCisReq->cisOffMaxUsec > (LCTR_CONN_IND_US(pCtx->connInterval) - (pCisReq->nse * pCisReq->subIntervUsec - pLctrRtCfg->cisSubEvtSpaceDelay))) + { + LL_TRACE_WARN0("LctrCheckCisReq: invalid parameters, cisOffMaxUsec is too big"); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Send CIS response PDU. + * + * \param pCtx Connection context. + * \param opcode PDU Opcode. + */ +/*************************************************************************************************/ +static void lctrSendCisRspPdu(lctrConnCtx_t *pCtx, uint8_t opcode) +{ + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_CIS_RSP_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + uint32_t cisOffMinUsec = lctrDataPdu.pld.cisReq.cisOffMinUsec; + uint32_t cisOffMaxUsec = lctrDataPdu.pld.cisReq.cisOffMaxUsec; + uint16_t ceRef = lctrDataPdu.pld.cisReq.ceRef; + + if (cisOffMinUsec != cisOffMaxUsec) + { + cisOffMinUsec = WSF_MAX(cisOffMinUsec, pCtx->connBod.minDurUsec + BbGetSchSetupDelayUs()); + + if (cisOffMinUsec > cisOffMaxUsec) + { + /* Cannot schedule the CIS. */ + LL_TRACE_WARN1("lctrSendCisRspPdu: Proposed offset cannot be scheduled within cisOffMaxUsec=%d", cisOffMaxUsec); + lctrSendRejectInd(pCtx, LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE, TRUE); + return; + } + } + + /*** Assemble control PDU ***/ + + UINT8_TO_BSTREAM (pBuf, opcode); + + #if (LL_ENABLE_TESTER) + if (llTesterCb.cisRspEnabled) + { + cisOffMinUsec = llTesterCb.cisOffMinUsec; + cisOffMaxUsec = llTesterCb.cisOffMaxUsec; + ceRef = llTesterCb.cisCeRef; + + llTesterCb.cisRspEnabled = FALSE; + } + #endif + UINT24_TO_BSTREAM (pBuf, cisOffMinUsec); + UINT24_TO_BSTREAM (pBuf, cisOffMaxUsec); + UINT16_TO_BSTREAM (pBuf, ceRef); + + /*** Queue for transmit ***/ + + lctrTxCtrlPduQueue(pCtx, pPdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send CIS response. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +static void lctrSendCisRsp(lctrConnCtx_t *pCtx) +{ + lctrSendCisRspPdu(pCtx, LL_PDU_CIS_RSP); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of peer CIS request event. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrNotifyHostCisReq(lctrCisCtx_t *pCisCtx) +{ + LlCisReqInd_t evt = + { + .hdr = + { + .param = pCisCtx->cisHandle, + .event = LL_CIS_REQ_IND, + .status = LL_SUCCESS + } + }; + + evt.aclHandle = pCisCtx->aclHandle; + evt.cisHandle = pCisCtx->cisHandle; + evt.cigId = pCisCtx->cigId; + evt.cisId = pCisCtx->cisId; + + LL_TRACE_INFO1("### LlEvent ### LL_CIS_REQ_IND, cisHandle=%u", pCisCtx->cisHandle); + + bool_t evtSent = LmgrSendEvent((LlEvt_t *)&evt); + + if (!evtSent) + { + LlRejectCisReq(pCisCtx->cisHandle, LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE); + LL_TRACE_WARN1("Host event masked; reply with reason=UNSUPPORTED_REMOTE_FEATURE, cisHandle=%u", pCisCtx->cisHandle); + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/************************************************************************************************** + CIS slave LLCP state machine action functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Action function for received peer CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActPeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + + WSF_ASSERT(pCigCtx); + + if (LctrCheckCisReq(pCtx, pCisCtx, &lctrDataPdu.pld.cisReq) != LL_SUCCESS) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_INVALID_LMP_PARAMS, TRUE); + lctrFreeCisCtx(pCisCtx); + LL_TRACE_WARN1("Invalid CIS request parameters; reply with reason=INVALID_LMP_PARAMS, cisHandle=%u", pCisCtx->cisHandle); + return; + } + + if ((lmgrCb.features & LL_FEAT_ISO_HOST_SUPPORT) == 0) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE, TRUE); + lctrFreeCisCtx(pCisCtx); + LL_TRACE_WARN0("Host did not set ISO channel support"); + return; + } + + lctrCisStorePeerCisReq(pCtx, pCisCtx); + + lctrNotifyHostCisReq(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received reject peer CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActRejCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrSendRejectInd(pCtx, pLctrConnMsg->rejCisReq.reason, TRUE); + + lctrCleanupCtx(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received accept peer CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActAcpCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + lctrSendCisRsp(pCtx); + lctrCisStartLlcpTimer(pCtx, pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received peer CIS indication. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActPeerCisInd(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + pCisCtx->accessAddr = lctrDataPdu.pld.cisInd.accessAddr; + pCisCtx->ceRef = lctrDataPdu.pld.cisInd.ceRef; + pCisCtx->crcInit = pCtx->crcInit; + pCisCtx->supTimeoutMs = pCtx->supTimeoutMs; + pCisCtx->offsetUsec = lctrDataPdu.pld.cisInd.cisOffUsec; + pCisCtx->cigSyncDelayUsec = lctrDataPdu.pld.cisInd.cigSyncDelayUsec; + pCisCtx->cisSyncDelayUsec = lctrDataPdu.pld.cisInd.cisSyncDelayUsec; + + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + + WSF_ASSERT(pCigCtx); + + if (pCigCtx->isBodBuilt == FALSE) + { + pCigCtx->cigSyncDelayUsec = lctrDataPdu.pld.cisInd.cigSyncDelayUsec; + pCigCtx->isoInterval = pCisCtx->isoInterval; /* All CISs have the same ISO interval. */ + + lctrCisSetupChanParam(pCisCtx, pCtx->chanMask); + lctrCisInsertHead(&pCigCtx->list, pCisCtx); + lctrSlvCisBuildCigOp(pCigCtx); + lctrCisSetupEncrypt(pCisCtx); + } + else + { + lctrCisSetupChanParam(pCisCtx, pCtx->chanMask); + lctrCisInsertTail(&pCigCtx->list, pCisCtx); + lctrSlvCisBuildCisData(pCisCtx); + lctrCisSetupEncrypt(pCisCtx); + } + + /* Calculate the offset for the stream. */ + if (pCisCtx->ceRef - pCtx->eventCounter >= 0x8000) + { + LL_TRACE_INFO0("lctrSlvCisLlcpActPeerCisInd, first anchor in the past"); + } + else + { + LL_TRACE_INFO0("lctrSlvCisLlcpActPeerCisInd, first anchor in the future"); + pCisCtx->data.slv.anchorOffsetUsec = (pCisCtx->ceRef - pCtx->eventCounter) * LCTR_CONN_IND_US(pCtx->connInterval) + pCisCtx->offsetUsec; + } + + if (pCigCtx->isBodStarted == FALSE) + { + pCigCtx->packing = LL_PACKING_SEQUENTIAL; /* One stream is the same as sequential. */ + + /* Commit BOD */ + lctrSlvCisCigOpCommit(pCigCtx, pCtx, pCisCtx); + pCisCtx->cisCeRef = 0; + } + else + { + /* Find the CIS reference event when CIS shall start transfer the CIS. */ + bool_t result = FALSE; + uint32_t aclRefTime, cigRefTime; + + aclRefTime = pCtx->data.slv.anchorPointUsec + (pCisCtx->ceRef - pCtx->eventCounter + 1) * LCTR_CONN_IND_US(pCtx->connInterval); /* Reference from the */ + pCisCtx->cisCeRef = 0; + + while (result == FALSE) + { + pCisCtx->cisCeRef++; + + if (pCigCtx->roleData.slv.cigEvtCounter == 0) + { + /* BOD is not started yet. */ + cigRefTime = pCigCtx->roleData.slv.anchorPointUsec + pCisCtx->cisCeRef * LCTR_ISO_INT_TO_US(pCigCtx->isoInterval); + } + else + { + cigRefTime = pCigCtx->roleData.slv.anchorPointUsec + (pCisCtx->cisCeRef + 1) * LCTR_ISO_INT_TO_US(pCigCtx->isoInterval); + } + + if (cigRefTime > aclRefTime) + { + result = TRUE; + } + } + + uint8_t cisCount = lctrCisGetListCount(&pCigCtx->list); + + /* Set packing scheme once when the second CISs is added, since all the rest follow the same scheme. */ + if (cisCount >= 2) + { + lctrCisCtx_t *pHeadCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + + if (cisCount == 2) + { + /* If the anchor point of the stream is before end of the first stream, it is interleaved packing scheme. */ + if (BbGetTargetTimeDelta(cigRefTime + pHeadCisCtx->subIntervUsec, + pCisCtx->data.slv.anchorOffsetUsec + pCtx->data.slv.anchorPointUsec + LCTR_CONN_IND_US(pCtx->connInterval)) > 0) + { + pCigCtx->packing = LL_PACKING_INTERLEAVED; + } + } + + /* Adjust delayUsec for two or more interleaved CISs, one for the original last one and one for the new last one. */ + if (pCigCtx->packing == LL_PACKING_INTERLEAVED) + { + lctrCisCtx_t *pCurCisCtx = lctrCisGetHeadCis(&pCigCtx->list); /* original last CIS */ + lctrCisCtx_t *pNextCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCurCisCtx); /* new last last CIS */ + + uint32_t prevDelayUsec = 0; + + while (cisCount > 2) + { + prevDelayUsec += pCurCisCtx->delayUsec; + pCurCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCurCisCtx); /* original last CIS */ + pNextCisCtx = lctrCisGetNextCis(&pCigCtx->list, pNextCisCtx); /* new last last CIS */ + + cisCount--; + } + + pCurCisCtx->delayUsec = pCisCtx->data.slv.anchorOffsetUsec + pCtx->data.slv.anchorPointUsec + LCTR_CONN_IND_US(pCtx->connInterval) - cigRefTime - prevDelayUsec; + pNextCisCtx->delayUsec = cigRefTime + pHeadCisCtx->subIntervUsec - (pCisCtx->data.slv.anchorOffsetUsec + pCtx->data.slv.anchorPointUsec + LCTR_CONN_IND_US(pCtx->connInterval)); + + LL_TRACE_ERR2("lctrSlvCisLlcpActPeerCisInd, handle=%d pCurCisCtx->delayUsec=%d", pCurCisCtx->cisHandle, pCurCisCtx->delayUsec); + LL_TRACE_ERR2("lctrSlvCisLlcpActPeerCisInd, handle=%d pNextCisCtx->delayUsec=%d", pNextCisCtx->cisHandle, pNextCisCtx->delayUsec); + } + else + { + lctrCisCtx_t *pPreCisCtx = lctrCisGetPreCis(&pCigCtx->list, pCisCtx); + lctrCisCtx_t *pTempCisCtx = pPreCisCtx; + + uint32_t prevDelayUsec = 0; + + while (cisCount > 2) + { + pTempCisCtx = lctrCisGetPreCis(&pCigCtx->list, pTempCisCtx); /* new last last CIS */ + prevDelayUsec += pTempCisCtx->nextCisOffsetUsec; + cisCount--; + } + + pPreCisCtx->nextCisOffsetUsec = pCisCtx->cigSyncDelayUsec - pCisCtx->cisSyncDelayUsec - prevDelayUsec; + + LL_TRACE_ERR1("lctrSlvCisLlcpActPeerCisInd, pPreCisCtx->nextCisOffsetUsec=%d", pPreCisCtx->nextCisOffsetUsec); + } + } + + + /* BOD is already committed, do nothing. */ + } + + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for store peer CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisStorePeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + memcpy(&pCisCtx->data.slv.cisReq, &lctrDataPdu.pld.cisReq, sizeof(lctrCisReq_t)); + + pCisCtx->cisId = lctrDataPdu.pld.cisReq.cisId; + pCisCtx->phyMToS = lctrPhysBitToPhy(lctrDataPdu.pld.cisReq.phyMToS); + pCisCtx->phySToM = lctrPhysBitToPhy(lctrDataPdu.pld.cisReq.phySToM); + pCisCtx->framing = lctrDataPdu.pld.cisReq.framing; + pCisCtx->sduSizeMToS = lctrDataPdu.pld.cisReq.sduSizeMToS; + pCisCtx->sduSizeSToM = lctrDataPdu.pld.cisReq.sduSizeSToM; + pCisCtx->sduIntervalMToS = lctrDataPdu.pld.cisReq.sduIntervalMToS; + pCisCtx->sduIntervalSToM = lctrDataPdu.pld.cisReq.sduIntervalSToM; + pCisCtx->localDataPdu.maxRxLen = lctrDataPdu.pld.cisReq.plMToS; + pCisCtx->localDataPdu.maxTxLen = lctrDataPdu.pld.cisReq.plSToM; + pCisCtx->nse = lctrDataPdu.pld.cisReq.nse; + pCisCtx->subIntervUsec = lctrDataPdu.pld.cisReq.subIntervUsec; + pCisCtx->bnMToS = lctrDataPdu.pld.cisReq.bnMToS; + pCisCtx->bnSToM = lctrDataPdu.pld.cisReq.bnSToM; + pCisCtx->ftMToS = lctrDataPdu.pld.cisReq.ftMToS; + pCisCtx->ftSToM = lctrDataPdu.pld.cisReq.ftSToM; + pCisCtx->isoInterval = lctrDataPdu.pld.cisReq.isoInterval; + pCisCtx->delayUsec = pCisCtx->subIntervUsec; /* If LL_PACKING_INTERLEAVED, delayUsec will be updated in lctrSlvCisLlcpActPeerCisInd */ +} + +/*************************************************************************************************/ +/*! + * \brief Action function for received peer CIS rejection. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActPeerCisRej(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + pCisCtx->reason = lctrDataPdu.pld.rejInd.reason; + + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_EST_FAIL); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for internal received peer CIS request. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisLlcpActIntPeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + if (LctrCheckCisReq(pCtx, pCisCtx, &pCisCtx->data.slv.cisReq) != LL_SUCCESS) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_INVALID_LMP_PARAMS, TRUE); + lctrFreeCisCtx(pCisCtx); + LL_TRACE_ERR1("Invalid CIS request parameters; reply with reason=INVALID_LMP_PARAMS, cisHandle=%u", pCisCtx->cisHandle); + return; + } + + if ((lmgrCb.features & LL_FEAT_ISO_HOST_SUPPORT) == 0) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE, TRUE); + lctrFreeCisCtx(pCisCtx); + LL_TRACE_WARN0("Host did not set ISO channel support"); + return; + } + + lctrCigCtx_t *pCigCtx; + if ((pCigCtx = lctrFindCigById(lctrDataPdu.pld.cisReq.cigId)) == NULL) + { + if ((pCigCtx = lctrAllocCigCtx(lctrDataPdu.pld.cisReq.cigId)) == NULL) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_LIMIT_REACHED, TRUE); + lctrFreeCisCtx(pCisCtx); + LL_TRACE_WARN0("Not able to allocate a CIG context"); + return; + } + } + + lctrNotifyHostCisReq(pCisCtx); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn.c index 4e42d521725..8456c14f02c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn.c @@ -1,32 +1,35 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller connection state machine action routines. + * \file + * + * \brief Link layer controller connection state machine action routines. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ +#include "ll_defs.h" #include "lctr_int_conn.h" #include "lctr_int_adv_slave.h" #include "lctr_int_adv_master_ae.h" #include "sch_api.h" #include "sch_api_ble.h" #include "lmgr_api_conn.h" +#include "pal_radio.h" #include "wsf_assert.h" #include "wsf_math.h" #include "wsf_msg.h" @@ -39,9 +42,6 @@ Macros **************************************************************************************************/ -/*! \brief Use special token to indicate no notification is required. */ -#define LCTR_RESET_TERM_REASON 0xFF - /*! \brief Valid feature bits applicable between controllers */ #define LCTR_FEAT_PEER_MASK (LL_FEAT_ENCRYPTION | \ LL_FEAT_CONN_PARAM_REQ_PROC | \ @@ -64,16 +64,17 @@ LL_FEAT_CIS_MASTER_ROLE | \ LL_FEAT_CIS_SLAVE_ROLE | \ LL_FEAT_ISO_BROADCASTER | \ - LL_FEAT_ISO_SYNC) - -/*! \brief Used feature bitmask, i.e. FeatureSet[0]. */ -#define LCTR_USED_FEAT_SET_MASK 0xFF + LL_FEAT_ISO_SYNC | \ + LL_FEAT_ISO_HOST_SUPPORT | \ + LL_FEAT_POWER_CONTROL_REQUEST | \ + LL_FEAT_POWER_CHANGE_IND | \ + LL_FEAT_PATH_LOSS_MONITOR) -/*! \brief Used feature bitmask, i.e. FeatureSet[0]. */ -#define LCTR_USED_FEAT_SET_MASK 0xFF +/*! \brief Used feature bitmask. */ +#define LCTR_USED_FEAT_SET_MASK 0x000000FFFF /*! \brief Features bits mask over the air */ -#define LCTR_OTA_FEAT_MASK (~LL_FEAT_REMOTE_PUB_KEY_VALIDATION & LL_FEAT_ALL_MASK) +#define LCTR_OTA_FEAT_MASK (~LL_FEAT_REMOTE_PUB_KEY_VALIDATION & LCTR_FEAT_PEER_MASK) /*************************************************************************************************/ /*! @@ -138,8 +139,6 @@ static uint8_t lctrComputeConnSca(lctrConnCtx_t *pCtx) * \param localRpa Local RPA. * \param status Status. * \param usedChSel Used channel selection algorithm. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostConnectInd(uint16_t handle, uint8_t role, lctrConnInd_t *pConnInd, @@ -208,8 +207,6 @@ void lctrNotifyHostConnectInd(uint16_t handle, uint8_t role, lctrConnInd_t *pCon * \brief Store connection update connection specification. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnUpdateSpec(lctrConnCtx_t *pCtx) @@ -222,8 +219,6 @@ void lctrStoreConnUpdateSpec(lctrConnCtx_t *pCtx) * \brief Store connect update parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnUpdate(lctrConnCtx_t *pCtx) @@ -243,8 +238,6 @@ void lctrStoreConnUpdate(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param status Status. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostConnUpdateInd(lctrConnCtx_t *pCtx, uint8_t status) @@ -281,8 +274,6 @@ void lctrNotifyHostConnUpdateInd(lctrConnCtx_t *pCtx, uint8_t status) * \brief Store channel map parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreChanMapUpdate(lctrConnCtx_t *pCtx) @@ -295,8 +286,6 @@ void lctrStoreChanMapUpdate(lctrConnCtx_t *pCtx) * \brief Send channel map update indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendChanMapUpdateInd(lctrConnCtx_t *pCtx) @@ -339,8 +328,6 @@ void lctrSendChanMapUpdateInd(lctrConnCtx_t *pCtx) * \brief Store channel map parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreChanMap(lctrConnCtx_t *pCtx) @@ -360,8 +347,6 @@ void lctrStoreChanMap(lctrConnCtx_t *pCtx) * \brief Send feature request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendFeatureReq(lctrConnCtx_t *pCtx) @@ -389,8 +374,6 @@ void lctrSendFeatureReq(lctrConnCtx_t *pCtx) * \brief Send feature response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendFeatureRsp(lctrConnCtx_t *pCtx) @@ -405,9 +388,9 @@ void lctrSendFeatureRsp(lctrConnCtx_t *pCtx) UINT8_TO_BSTREAM(pBuf, LL_PDU_FEATURE_RSP); - uint64_t featSet = (pCtx->usedFeatSet & LCTR_USED_FEAT_SET_MASK) | /* FeatureSet[0] used by master and slave */ - (lmgrCb.features & ~LCTR_USED_FEAT_SET_MASK); /* FeatureSet[1..7] used by sender */ - UINT64_TO_BSTREAM(pBuf, (featSet & LCTR_OTA_FEAT_MASK)); /* Only send valid features bits between controllers. */ + uint64_t featSet = (pCtx->usedFeatSet & LCTR_USED_FEAT_SET_MASK) | /* FeatureSet[0] used by master and slave */ + (lmgrCb.features & ~LCTR_USED_FEAT_SET_MASK); /* FeatureSet[1..7] used by sender */ + UINT64_TO_BSTREAM(pBuf, (featSet & LCTR_OTA_FEAT_MASK)); /* Only send valid features bits between controllers. */ /*** Queue for transmit. ***/ @@ -420,8 +403,6 @@ void lctrSendFeatureRsp(lctrConnCtx_t *pCtx) * \brief Store remote feature data. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreUsedFeatures(lctrConnCtx_t *pCtx) @@ -441,8 +422,6 @@ void lctrStoreUsedFeatures(lctrConnCtx_t *pCtx) * \brief Send version indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendVersionInd(lctrConnCtx_t *pCtx) @@ -481,8 +460,6 @@ void lctrSendVersionInd(lctrConnCtx_t *pCtx) * \brief Store remote version data. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreRemoteVer(lctrConnCtx_t *pCtx) @@ -499,8 +476,6 @@ void lctrStoreRemoteVer(lctrConnCtx_t *pCtx) * \brief Notify host of read remote version confirm. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostReadRemoteVerCnf(lctrConnCtx_t *pCtx) @@ -533,8 +508,6 @@ void lctrNotifyHostReadRemoteVerCnf(lctrConnCtx_t *pCtx) * \brief Send terminate indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendTerminateInd(lctrConnCtx_t *pCtx) @@ -562,8 +535,6 @@ void lctrSendTerminateInd(lctrConnCtx_t *pCtx) * \brief Notify host of disconnect indication. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostDisconnectInd(lctrConnCtx_t *pCtx) @@ -603,8 +574,6 @@ void lctrNotifyHostDisconnectInd(lctrConnCtx_t *pCtx) * \brief Store LLCP termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreTerminateReason(lctrConnCtx_t *pCtx) @@ -620,8 +589,6 @@ void lctrStoreTerminateReason(lctrConnCtx_t *pCtx) * \brief Store host initiated disconnect termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreDisconnectReason(lctrConnCtx_t *pCtx) @@ -634,8 +601,6 @@ void lctrStoreDisconnectReason(lctrConnCtx_t *pCtx) * \brief Store connection failed to establish termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnFailEstablishTerminateReason(lctrConnCtx_t *pCtx) @@ -648,8 +613,6 @@ void lctrStoreConnFailEstablishTerminateReason(lctrConnCtx_t *pCtx) * \brief Store LLCP timeout termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreLlcpTimeoutTerminateReason(lctrConnCtx_t *pCtx) @@ -662,8 +625,6 @@ void lctrStoreLlcpTimeoutTerminateReason(lctrConnCtx_t *pCtx) * \brief Store reset termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreResetTerminateReason(lctrConnCtx_t *pCtx) @@ -676,8 +637,6 @@ void lctrStoreResetTerminateReason(lctrConnCtx_t *pCtx) * \brief Store invalid request termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreInstantPassedTerminateReason(lctrConnCtx_t *pCtx) @@ -690,8 +649,6 @@ void lctrStoreInstantPassedTerminateReason(lctrConnCtx_t *pCtx) * \brief Store invalid request termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreMicFailedTerminateReason(lctrConnCtx_t *pCtx) @@ -704,8 +661,6 @@ void lctrStoreMicFailedTerminateReason(lctrConnCtx_t *pCtx) * \brief Store connection parameter request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnParamReq(lctrConnCtx_t *pCtx) @@ -718,8 +673,6 @@ void lctrStoreConnParamReq(lctrConnCtx_t *pCtx) * \brief Store connection parameter request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnParamRsp(lctrConnCtx_t *pCtx) @@ -779,8 +732,6 @@ void lctrStoreConnParamRsp(lctrConnCtx_t *pCtx) * \brief Store connection parameter connection specification. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreConnParamSpec(lctrConnCtx_t *pCtx) @@ -796,8 +747,6 @@ void lctrStoreConnParamSpec(lctrConnCtx_t *pCtx) * \param opcode Pdu Opcode. * \param pConnSpec Connection specification. * \param prefPeriod Preferred periodicity. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendConnParamPdu(lctrConnCtx_t *pCtx, uint8_t opcode, LlConnSpec_t *pConnSpec, uint8_t prefPeriod) @@ -837,8 +786,6 @@ static void lctrSendConnParamPdu(lctrConnCtx_t *pCtx, uint8_t opcode, LlConnSpec * \brief Send connection parameter request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendConnParamReq(lctrConnCtx_t *pCtx) @@ -861,7 +808,10 @@ void lctrSendConnParamReq(lctrConnCtx_t *pCtx) } #endif - lctrSendConnParamPdu(pCtx, LL_PDU_CONN_PARAM_REQ, &pCtx->connUpdSpec, LCTR_US_TO_CONN_IND(SchRmPreferredPeriodUsec())); + uint8_t prefPeriod = (LCTR_US_TO_CONN_IND(SCH_RM_PREF_PER_USEC) <= pCtx->connUpdSpec.connIntervalMax) ? + LCTR_US_TO_CONN_IND(SCH_RM_PREF_PER_USEC) + : LCTR_US_TO_CONN_IND(SCH_RM_PREF_PER_USEC_LOWEST); + lctrSendConnParamPdu(pCtx, LL_PDU_CONN_PARAM_REQ, &pCtx->connUpdSpec, prefPeriod); } /*************************************************************************************************/ @@ -869,8 +819,6 @@ void lctrSendConnParamReq(lctrConnCtx_t *pCtx) * \brief Send connection parameter response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendConnParamRsp(lctrConnCtx_t *pCtx) @@ -889,8 +837,6 @@ void lctrSendConnParamRsp(lctrConnCtx_t *pCtx) * \brief Notify host of remote connection parameter change indication. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostConnParamInd(lctrConnCtx_t *pCtx) @@ -913,7 +859,7 @@ void lctrNotifyHostConnParamInd(lctrConnCtx_t *pCtx) return; } - if ((pCtx->connParam.connIntervalMin != pCtx->connInterval) || // TODO compare to original conn min/max? + if ((pCtx->connParam.connIntervalMin != pCtx->connInterval) || /* TODO compare to original conn min/max? */ (pCtx->connParam.connIntervalMax != pCtx->connInterval) || (pCtx->connParam.connLatency != pCtx->maxLatency) || (LCTR_CONN_IND_TO_MS(pCtx->connParam.supTimeout) != pCtx->supTimeoutMs)) @@ -955,8 +901,6 @@ void lctrNotifyHostConnParamInd(lctrConnCtx_t *pCtx) * \brief Store local data length parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreLocalDataLength(lctrConnCtx_t *pCtx) @@ -983,8 +927,6 @@ void lctrStoreLocalDataLength(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param opcode PDU opcode. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendDataLengthPdu(lctrConnCtx_t *pCtx, uint8_t opcode) @@ -1003,8 +945,9 @@ static void lctrSendDataLengthPdu(lctrConnCtx_t *pCtx, uint8_t opcode) uint16_t maxRxTime = pCtx->localDataPdu.maxRxTime; uint16_t maxTxTime = pCtx->localDataPdu.maxTxTime; - /* If LL_FEAT_LE_CODED_PHY is not supported, maxRxTime and maxTxTime can not be more than 2120. */ - if (!(pCtx->usedFeatSet & LL_FEAT_LE_CODED_PHY)) + /* If LL_FEAT_LE_CODED_PHY is not supported, maxRxTime and maxTxTime can not be more than 2128.*/ + if (!pCtx->featExchFlag || + !(pCtx->usedFeatSet & LL_FEAT_LE_CODED_PHY)) { maxRxTime = WSF_MIN(pCtx->localDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MAX_1M); maxTxTime = WSF_MIN(pCtx->localDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MAX_1M); @@ -1037,8 +980,6 @@ static void lctrSendDataLengthPdu(lctrConnCtx_t *pCtx, uint8_t opcode) * \brief Send data length request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendDataLengthReq(lctrConnCtx_t *pCtx) @@ -1051,8 +992,6 @@ void lctrSendDataLengthReq(lctrConnCtx_t *pCtx) * \brief Send data length response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendDataLengthRsp(lctrConnCtx_t *pCtx) @@ -1065,8 +1004,6 @@ void lctrSendDataLengthRsp(lctrConnCtx_t *pCtx) * \brief Store remote data length parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreRemoteDataLength(lctrConnCtx_t *pCtx) @@ -1086,8 +1023,9 @@ void lctrStoreRemoteDataLength(lctrConnCtx_t *pCtx) uint16_t maxRxTime = pCtx->localDataPdu.maxRxTime; uint16_t maxTxTime = pCtx->localDataPdu.maxTxTime; - /* If LL_FEAT_LE_CODED_PHY is not supported, maxRxTime and maxTxTime can not be more than 2120. */ - if (!(pCtx->usedFeatSet & LL_FEAT_LE_CODED_PHY)) + /* If LL_FEAT_LE_CODED_PHY is not supported, maxRxTime and maxTxTime can not be more than 2128. */ + if (!pCtx->featExchFlag || + !(pCtx->usedFeatSet & LL_FEAT_LE_CODED_PHY)) { maxRxTime = WSF_MIN(pCtx->localDataPdu.maxRxTime, LL_MAX_DATA_TIME_ABS_MAX_1M); maxTxTime = WSF_MIN(pCtx->localDataPdu.maxTxTime, LL_MAX_DATA_TIME_ABS_MAX_1M); @@ -1129,8 +1067,6 @@ void lctrStoreRemoteDataLength(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param status Status. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostDataLengthInd(lctrConnCtx_t *pCtx, uint8_t status) @@ -1164,8 +1100,6 @@ void lctrNotifyHostDataLengthInd(lctrConnCtx_t *pCtx, uint8_t status) * \brief Send set minimum number of used channels indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendSetMinUsedChanPdu(lctrConnCtx_t *pCtx) @@ -1193,8 +1127,6 @@ static void lctrSendSetMinUsedChanPdu(lctrConnCtx_t *pCtx) * \brief Send set minimum number of used channels indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendSetMinUsedChanInd(lctrConnCtx_t *pCtx) @@ -1211,8 +1143,6 @@ void lctrSendSetMinUsedChanInd(lctrConnCtx_t *pCtx) * \brief Store remote minimum number of used channels parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreSetMinUsedChan(lctrConnCtx_t *pCtx) @@ -1236,8 +1166,6 @@ void lctrStoreSetMinUsedChan(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param opcode PDU opcode. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendPeerScaReqPdu(lctrConnCtx_t *pCtx, uint8_t opcode) @@ -1262,8 +1190,6 @@ static void lctrSendPeerScaReqPdu(lctrConnCtx_t *pCtx, uint8_t opcode) * \brief Update action for sca processing. * * \param pCtx Connection Context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreScaAction(lctrConnCtx_t *pCtx) @@ -1276,8 +1202,6 @@ void lctrStoreScaAction(lctrConnCtx_t *pCtx) * \brief Send peer SCA request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPeerScaReq(lctrConnCtx_t *pCtx) @@ -1312,8 +1236,6 @@ void lctrSendPeerScaReq(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param opcode PDU opcode. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendPeerScaRspPdu(lctrConnCtx_t *pCtx, uint8_t opcode) @@ -1338,8 +1260,6 @@ static void lctrSendPeerScaRspPdu(lctrConnCtx_t *pCtx, uint8_t opcode) * \brief Send peer SCA response. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPeerScaRsp(lctrConnCtx_t *pCtx) @@ -1352,8 +1272,6 @@ void lctrSendPeerScaRsp(lctrConnCtx_t *pCtx) * \brief Store peer SCA. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStorePeerSca(lctrConnCtx_t *pCtx) @@ -1373,8 +1291,6 @@ void lctrStorePeerSca(lctrConnCtx_t *pCtx) * \brief Notify host of peer SCA request confirmation. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostPeerScaCnf(lctrConnCtx_t *pCtx) @@ -1405,8 +1321,6 @@ void lctrNotifyHostPeerScaCnf(lctrConnCtx_t *pCtx) * \brief Send unknown response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendUnknownRsp(lctrConnCtx_t *pCtx) @@ -1435,8 +1349,6 @@ void lctrSendUnknownRsp(lctrConnCtx_t *pCtx) * \param pCtx Connection context. * \param reason Reason code. * \param forceRejectExtInd TRUE to force using LL_REJECT_EXT_IND. - * - * \return None. */ /*************************************************************************************************/ void lctrSendRejectInd(lctrConnCtx_t *pCtx, uint8_t reason, bool_t forceRejectExtInd) @@ -1488,8 +1400,6 @@ void lctrSendRejectInd(lctrConnCtx_t *pCtx, uint8_t reason, bool_t forceRejectEx * \brief Start LLCP timer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStartLlcpTimer(lctrConnCtx_t *pCtx) @@ -1512,8 +1422,6 @@ void lctrStartLlcpTimer(lctrConnCtx_t *pCtx) * \brief Stop LLCP timer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStopLlcpTimer(lctrConnCtx_t *pCtx) @@ -1529,8 +1437,6 @@ void lctrStopLlcpTimer(lctrConnCtx_t *pCtx) * \brief Start pending LLCP procedure. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStartPendingLlcp(lctrConnCtx_t *pCtx) @@ -1543,8 +1449,6 @@ void lctrStartPendingLlcp(lctrConnCtx_t *pCtx) * \brief Pause Tx data PDUs. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrPauseTxData(lctrConnCtx_t *pCtx) @@ -1558,8 +1462,6 @@ void lctrPauseTxData(lctrConnCtx_t *pCtx) * \brief Unpause Tx data PDUs. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrUnpauseTxData(lctrConnCtx_t *pCtx) @@ -1594,8 +1496,6 @@ void lctrUnpauseTxData(lctrConnCtx_t *pCtx) * \brief Check if Tx data pending. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrCheckPauseComplete(lctrConnCtx_t *pCtx) @@ -1611,8 +1511,6 @@ void lctrCheckPauseComplete(lctrConnCtx_t *pCtx) * \brief Pause Rx data PDUs. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrPauseRxData(lctrConnCtx_t *pCtx) @@ -1626,8 +1524,6 @@ void lctrPauseRxData(lctrConnCtx_t *pCtx) * \brief Unpause Rx data PDUs. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrUnpauseRxData(lctrConnCtx_t *pCtx) @@ -1641,8 +1537,6 @@ void lctrUnpauseRxData(lctrConnCtx_t *pCtx) * \brief Store periodic advertising sync transfer parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx) @@ -1658,8 +1552,6 @@ void lctrActStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx) * \brief Send periodic sync indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActSendPeriodicSyncInd(lctrConnCtx_t *pCtx) @@ -1675,8 +1567,6 @@ void lctrActSendPeriodicSyncInd(lctrConnCtx_t *pCtx) * \brief Handle received periodic sync indication PDU. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActReceivePeriodicSyncInd(lctrConnCtx_t *pCtx) @@ -1686,3 +1576,4 @@ void lctrActReceivePeriodicSyncInd(lctrConnCtx_t *pCtx) lctrReceivePeriodicSyncIndFn(pCtx); } } + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master.c index 877b5d79f5c..10283eb71e3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection state machine action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection state machine action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ * \brief Send connection update request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendConnUpdateInd(lctrConnCtx_t *pCtx) @@ -59,7 +58,7 @@ void lctrSendConnUpdateInd(lctrConnCtx_t *pCtx) uint32_t interMinUsec = LCTR_CONN_IND_US(pCtx->connUpdSpec.connIntervalMin); uint32_t interMaxUsec = LCTR_CONN_IND_US(pCtx->connUpdSpec.connIntervalMax); - uint32_t durUsec = pCtx->localConnDurUsec; + uint32_t durUsec = pCtx->effConnDurUsec; uint32_t connIntervalUsec; /* Accommodate peer PreferredPeriodicity. */ @@ -83,8 +82,6 @@ void lctrSendConnUpdateInd(lctrConnCtx_t *pCtx) * \brief Reload an empty BOD with a data PDU. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrMstReloadDataPdu(lctrConnCtx_t *pCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master_ae.c index 6244a302adf..f51c6074c38 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection state machine action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection state machine action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -51,7 +52,7 @@ static uint8_t lctrExtInitSetupConn(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t uint32_t interMinUsec = LCTR_CONN_IND_US(pConnSpec->connIntervalMin); uint32_t interMaxUsec = LCTR_CONN_IND_US(pConnSpec->connIntervalMax); - uint32_t durUsec = pCtx->localConnDurUsec; + uint32_t durUsec = pCtx->effConnDurUsec; if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), SCH_RM_PREF_PERFORMANCE, interMinUsec, interMaxUsec, durUsec, &connInterUsec, lctrGetConnRefTime)) { @@ -97,7 +98,6 @@ uint8_t lctrExtInitSetupInitiate(lctrExtScanCtx_t *pExtInitCtx, uint8_t peerAddr pExtInitCtx->bodTermCnt = 0; pExtInitCtx->data.init.filtPolicy = filtPolicy; pExtInitCtx->data.init.ownAddrType = ownAddrType; - pExtInitCtx->data.init.connBodLoaded = FALSE; BbStart(BB_PROT_BLE); @@ -137,8 +137,6 @@ uint8_t lctrExtInitSetupInitiate(lctrExtScanCtx_t *pExtInitCtx, uint8_t peerAddr * \brief Establish connection. * * \param pExtInitCtx Extended initiate context. - * - * \return None. */ /*************************************************************************************************/ void lctrExtInitActConnect(lctrExtScanCtx_t *pExtInitCtx) @@ -195,8 +193,6 @@ void lctrExtInitActConnect(lctrExtScanCtx_t *pExtInitCtx) * \brief Common initiate resource cleanup. * * \param pExtInitCtx Extended initiate context. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtInitCleanupOp(lctrExtScanCtx_t *pExtInitCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_past.c index f400f3a303a..4e5965808ab 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_conn_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller connection state machine action routines for PAST feature. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller connection state machine action routines for PAST feature. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -41,8 +42,6 @@ * * \param pCtx Connection context. * - * \return None. - * * This function is called from BOD end callback of master/slave connection. */ /*************************************************************************************************/ @@ -71,33 +70,33 @@ void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx) /* Find PEa, event counter of PE whose starting time is after CEref. */ uint16_t paEventCounter = pPerScanCtx->lastActiveEvent; - uint32_t paAnchor = pPerScanCtx->lastAnchorPoint; + uint32_t paAnchor = pPerScanCtx->lastAnchorPointUsec; uint32_t ceRefStart, ceRefEnd; /* Calculate the end time of CEref. */ ceRefStart = lctrConnGetAnchorPoint(pCtx, (pCtx->eventCounter + ceOffset)); - ceRefEnd = ceRefStart + BB_US_TO_BB_TICKS(pCtx->localConnDurUsec + BbGetSchSetupDelayUs()); + ceRefEnd = ceRefStart + pCtx->effConnDurUsec + BbGetSchSetupDelayUs(); /* paAnchor is for the first PE in the future from ceRefEnd. */ - if ((ceRefEnd - paAnchor) < LCTR_SCH_MAX_SPAN) + if (BbGetTargetTimeDelta(ceRefEnd, paAnchor) > 0) { - uint16_t numPE = (ceRefEnd - paAnchor) / pPerScanCtx->perInter + 1; + uint16_t numPE = BbGetTargetTimeDelta(ceRefEnd, paAnchor) / pPerScanCtx->perInterUsec + 1; - paAnchor += numPE * pPerScanCtx->perInter; + paAnchor += numPE * pPerScanCtx->perInterUsec; paEventCounter += numPE; } else { - uint16_t numPE = (paAnchor - ceRefEnd) / pPerScanCtx->perInter; + uint16_t numPE = BbGetTargetTimeDelta(paAnchor, ceRefEnd) / pPerScanCtx->perInterUsec; - paAnchor -= numPE * pPerScanCtx->perInter; + paAnchor -= numPE * pPerScanCtx->perInterUsec; paEventCounter -= numPE; } uint8_t offsUnits; uint8_t offsAdjust = 0; uint16_t offs; - uint32_t offsUsec = BB_TICKS_TO_US(paAnchor - ceRefStart); + uint32_t offsUsec = BbGetTargetTimeDelta(paAnchor, ceRefStart); if (offsUsec < LL_30_USEC_OFFS_MAX_USEC) { @@ -117,7 +116,7 @@ void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx) } LL_TRACE_INFO1("LL_PERIODIC_SYNC_IND from SCAN ceRef anchor point = %u", ceRefStart); - LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerScanCtx->lastAnchorPoint); + LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerScanCtx->lastAnchorPointUsec); LL_TRACE_INFO1(" PA REF paAnchor = %u", paAnchor); LL_TRACE_INFO1(" offsUsec = %u", offsUsec); @@ -130,7 +129,7 @@ void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx) (offsUnits << 13) | /* Offset units. */ (offsAdjust << 14)); /* Offset adjust. */ - UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pPerScanCtx->perInter))); /* Interval */ + UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(pPerScanCtx->perInterUsec)); /* Interval */ uint64_t temp = pPerScanCtx->chanParam.chanMask | /* SyncInfo - ChMap */ ((uint64_t)pPerScanCtx->sca << 37); /* SyncInfo - SCA of the device sending AUX_SYNC_IND. */ @@ -161,8 +160,6 @@ void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * - * \return None. - * * This function is called from BOD end callback of master/slave connection. */ /*************************************************************************************************/ @@ -194,33 +191,33 @@ void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx) /* Find PEa, event counter of PE whose starting time is after CEref. */ uint16_t paEventCounter = pAdvSet->perParam.perEventCounter; - uint32_t paAnchor = pPerOp->due; + uint32_t paAnchor = pPerOp->dueUsec; uint32_t ceRefStart, ceRefEnd; /* Calculate the end time of CEref. */ ceRefStart = lctrConnGetAnchorPoint(pCtx, (pCtx->eventCounter + ceOffset)); - ceRefEnd = ceRefStart + BB_US_TO_BB_TICKS(pCtx->localConnDurUsec + BbGetSchSetupDelayUs()); + ceRefEnd = ceRefStart + pCtx->effConnDurUsec + BbGetSchSetupDelayUs(); /* paAnchor is for the first PE in the future from ceRefEnd. */ - if ((ceRefEnd - paAnchor) < LCTR_SCH_MAX_SPAN) + if (BbGetTargetTimeDelta(ceRefEnd, paAnchor) > 0) { - uint16_t numPE = (ceRefEnd - paAnchor) / pAdvSet->perParam.perAdvInter + 1; + uint16_t numPE = BbGetTargetTimeDelta(ceRefEnd, paAnchor) / pAdvSet->perParam.perAdvInterUsec + 1; - paAnchor += numPE * pAdvSet->perParam.perAdvInter; + paAnchor += numPE * pAdvSet->perParam.perAdvInterUsec; paEventCounter += numPE; } else { - uint16_t numPE = (paAnchor - ceRefEnd) / pAdvSet->perParam.perAdvInter; + uint16_t numPE = BbGetTargetTimeDelta(paAnchor, ceRefEnd) / pAdvSet->perParam.perAdvInterUsec; - paAnchor -= numPE * pAdvSet->perParam.perAdvInter; + paAnchor -= numPE * pAdvSet->perParam.perAdvInterUsec; paEventCounter -= numPE; } uint8_t offsUnits; uint8_t offsAdjust = 0; uint16_t offs; - uint32_t offsUsec = BB_TICKS_TO_US(paAnchor - ceRefStart); + uint32_t offsUsec = BbGetTargetTimeDelta(paAnchor, ceRefStart); if (offsUsec < LL_30_USEC_OFFS_MAX_USEC) { @@ -240,7 +237,7 @@ void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx) } LL_TRACE_INFO1("LL_PERIODIC_SYNC_IND from BCST ceRef anchor point = %u", ceRefStart); - LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerOp->due); + LL_TRACE_INFO1(" PA lastAnchorPoint = %u", pPerOp->dueUsec); LL_TRACE_INFO1(" PA REF paAnchor = %u", paAnchor); LL_TRACE_INFO1(" offsUsec = %u", offsUsec); @@ -253,7 +250,7 @@ void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx) (offsUnits << 13) | /* Offset units. */ (offsAdjust << 14)); /* Offset adjust. */ - UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter))); /* Interval */ + UINT16_TO_BSTREAM(pBuf, LCTR_PER_INTER_TO_MS(pAdvSet->perParam.perAdvInterUsec)); /* Interval */ uint64_t temp = pAdvSet->perParam.perChanParam.chanMask | /* SyncInfo - ChMap */ ((uint64_t)lctrComputeSca() << 37); /* SyncInfo - SCA of the device sending AUX_SYNC_IND. */ @@ -295,8 +292,6 @@ void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx) * \brief Store periodic advertising sync transfer parameters. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx) @@ -311,8 +306,6 @@ void lctrStorePeriodicSyncTrsf(lctrConnCtx_t *pCtx) * \brief Send periodic sync indication PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPeriodicSyncInd(lctrConnCtx_t *pCtx) @@ -333,8 +326,6 @@ void lctrSendPeriodicSyncInd(lctrConnCtx_t *pCtx) * \brief Handle received periodic sync indication PDU. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrReceivePeriodicSyncInd(lctrConnCtx_t *pCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc.c index 8aabf6cf059..f574180096b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave encryption action routines. + * \file + * + * \brief Link layer controller slave encryption action routines. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,7 +28,7 @@ #include "wsf_msg.h" #include "wsf_trace.h" #include "util/bstream.h" -#include "stack/platform/include/pal_crypto.h" +#include "pal_crypto.h" #include /*************************************************************************************************/ @@ -35,8 +36,6 @@ * \brief Modify encryption mode. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrModifyEncMode(lctrConnCtx_t *pCtx) @@ -68,8 +67,6 @@ static void lctrModifyEncMode(lctrConnCtx_t *pCtx) * \brief Enable Tx data encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrEnableTxDataEnc(lctrConnCtx_t *pCtx) @@ -85,8 +82,6 @@ void lctrEnableTxDataEnc(lctrConnCtx_t *pCtx) * \brief Enable Tx data encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrDisableTxDataEnc(lctrConnCtx_t *pCtx) @@ -100,8 +95,6 @@ void lctrDisableTxDataEnc(lctrConnCtx_t *pCtx) * \brief Enable Rx data encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrEnableRxDataEnc(lctrConnCtx_t *pCtx) @@ -117,8 +110,6 @@ void lctrEnableRxDataEnc(lctrConnCtx_t *pCtx) * \brief Enable Rx data encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrDisableRxDataEnc(lctrConnCtx_t *pCtx) @@ -132,8 +123,6 @@ void lctrDisableRxDataEnc(lctrConnCtx_t *pCtx) * \brief Generate slave encryption vectors. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateSlvVectors(lctrConnCtx_t *pCtx) @@ -157,8 +146,6 @@ void lctrGenerateSlvVectors(lctrConnCtx_t *pCtx) * \brief Store LTK reply. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreLtkReply(lctrConnCtx_t *pCtx) @@ -171,8 +158,6 @@ void lctrStoreLtkReply(lctrConnCtx_t *pCtx) * \brief Store LTK negative reply termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreLtkNegRepTerminateReason(lctrConnCtx_t *pCtx) @@ -185,8 +170,6 @@ void lctrStoreLtkNegRepTerminateReason(lctrConnCtx_t *pCtx) * \brief Calculate session keys. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrCalcSessionKey(lctrConnCtx_t *pCtx) @@ -198,9 +181,11 @@ void lctrCalcSessionKey(lctrConnCtx_t *pCtx) WSF_ASSERT(lctrInitCipherBlkHdlr); memcpy(pEnc->iv, pCtx->iv, sizeof(pEnc->iv)); - uint8_t dir = (pCtx->role == LL_ROLE_MASTER) ? 1 : 0; /* master = 1; slave = 0 */ + pEnc->dir = (pCtx->role == LL_ROLE_MASTER) ? 1 : 0; /* master = 1; slave = 0 */ pEnc->type = PAL_BB_TYPE_ACL; - lctrInitCipherBlkHdlr(pEnc, LCTR_GET_CONN_HANDLE(pCtx), dir); + pCtx->txPktCounter = 0; + pCtx->rxPktCounter = 0; + lctrInitCipherBlkHdlr(pEnc, LCTR_GET_CONN_HANDLE(pCtx), pEnc->dir); } /*************************************************************************************************/ @@ -208,8 +193,6 @@ void lctrCalcSessionKey(lctrConnCtx_t *pCtx) * \brief Send feature response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrInvalidEncPduSeq(lctrConnCtx_t *pCtx) @@ -223,8 +206,6 @@ void lctrInvalidEncPduSeq(lctrConnCtx_t *pCtx) * \brief Send feature response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendEncRsp(lctrConnCtx_t *pCtx) @@ -255,8 +236,6 @@ void lctrSendEncRsp(lctrConnCtx_t *pCtx) * \brief Send start encryption request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendStartEncReq(lctrConnCtx_t *pCtx) @@ -282,8 +261,6 @@ void lctrSendStartEncReq(lctrConnCtx_t *pCtx) * \brief Send start encryption response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendStartEncRsp(lctrConnCtx_t *pCtx) @@ -309,8 +286,6 @@ void lctrSendStartEncRsp(lctrConnCtx_t *pCtx) * \brief Send pause encryption request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPauseEncReq(lctrConnCtx_t *pCtx) @@ -336,8 +311,6 @@ void lctrSendPauseEncReq(lctrConnCtx_t *pCtx) * \brief Send pause encryption response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPauseEncRsp(lctrConnCtx_t *pCtx) @@ -363,8 +336,6 @@ void lctrSendPauseEncRsp(lctrConnCtx_t *pCtx) * \brief Send ping request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPingReq(lctrConnCtx_t *pCtx) @@ -390,8 +361,6 @@ void lctrSendPingReq(lctrConnCtx_t *pCtx) * \brief Send ping response PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPingRsp(lctrConnCtx_t *pCtx) @@ -417,8 +386,6 @@ void lctrSendPingRsp(lctrConnCtx_t *pCtx) * \brief Notify slave host of connect indication. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrEncNotifyHostLtkReqInd(lctrConnCtx_t *pCtx) @@ -451,8 +418,6 @@ void lctrEncNotifyHostLtkReqInd(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * \param status Status code. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyEncChangeInd(lctrConnCtx_t *pCtx, uint8_t status) @@ -484,8 +449,6 @@ void lctrNotifyEncChangeInd(lctrConnCtx_t *pCtx, uint8_t status) * \brief Notify host of key refreshed. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyEncKeyRefreshInd(lctrConnCtx_t *pCtx) @@ -515,8 +478,6 @@ void lctrNotifyEncKeyRefreshInd(lctrConnCtx_t *pCtx) * \brief Notify host of authentication payload timeout expired. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyAuthPayloadTimeout(lctrConnCtx_t *pCtx) @@ -545,8 +506,6 @@ void lctrNotifyAuthPayloadTimeout(lctrConnCtx_t *pCtx) * \brief Restart authentication payload timeout timer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrRestartAuthPayloadTimer(lctrConnCtx_t *pCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc_master.c index ad41679dd75..9a54a02e7aa 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master encryption action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master encryption action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ * \brief Generate master encryption vectors. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateMstVectors(lctrConnCtx_t *pCtx) @@ -58,8 +57,6 @@ void lctrGenerateMstVectors(lctrConnCtx_t *pCtx) * \brief Generate master encryption vectors. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreSlvVectors(lctrConnCtx_t *pCtx) @@ -74,8 +71,6 @@ void lctrStoreSlvVectors(lctrConnCtx_t *pCtx) * \brief Send encryption request PDU to peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrSendEncReq(lctrConnCtx_t *pCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master.c index af4f09235da..d917f110be7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection state machine action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection state machine action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,13 +27,12 @@ #include "sch_api_ble.h" #include "wsf_trace.h" #include "util/bstream.h" +#include "lctr_int_conn.h" #include /*************************************************************************************************/ /*! * \brief Start initiate connection scan. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActInitiate(void) @@ -54,7 +54,7 @@ void lctrInitActInitiate(void) uint32_t interMinUsec = LCTR_CONN_IND_US(pInitMsg->connSpec.connIntervalMin); uint32_t interMaxUsec = LCTR_CONN_IND_US(pInitMsg->connSpec.connIntervalMax); - uint32_t durUsec = pCtx->localConnDurUsec; + uint32_t durUsec = pCtx->effConnDurUsec; if (!SchRmAdd(LCTR_GET_CONN_HANDLE(pCtx), SCH_RM_PREF_PERFORMANCE, interMinUsec, interMaxUsec, durUsec, &connInterUsec, lctrGetConnRefTime)) { @@ -83,7 +83,6 @@ void lctrInitActInitiate(void) lctrMstInit.data.init.connHandle = LCTR_GET_CONN_HANDLE(pCtx); lctrMstInit.data.init.connInterval = LCTR_US_TO_CONN_IND(connInterUsec); - lctrMstInit.data.init.connBodLoaded = FALSE; lctrMstInit.scanParam = pInitMsg->scanParam; BbStart(BB_PROT_BLE); @@ -113,8 +112,6 @@ void lctrInitActInitiate(void) /*************************************************************************************************/ /*! * \brief Establish connection. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActConnect(void) @@ -169,8 +166,6 @@ void lctrInitActConnect(void) /*************************************************************************************************/ /*! * \brief Shutdown active initiation operation. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActShutdown(void) @@ -191,19 +186,17 @@ void lctrInitActShutdown(void) /*************************************************************************************************/ /*! * \brief Terminated scan after host initiate disable. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActScanTerm(void) { + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle); + lctrSendConnMsg(pConnCtx, LCTR_CONN_INIT_CANCELED); + BbStop(BB_PROT_BLE); lctrScanCleanup(&lctrMstInit); - SchRmRemove(lctrMstInit.data.init.connHandle); - lctrFreeConnCtx(LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle)); - LlCreateConnCancelCnf_t evt = { .hdr = @@ -228,21 +221,22 @@ void lctrInitActScanTerm(void) /*************************************************************************************************/ /*! * \brief Terminated scan after host reset. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActResetTerm(void) { + + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle); + lctrSendConnMsg(pConnCtx, LCTR_CONN_TERMINATED); + BbStop(BB_PROT_BLE); + lctrScanCleanup(&lctrMstInit); } /*************************************************************************************************/ /*! * \brief Notify host disallowing initiate. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActDisallowInitiate(void) @@ -255,8 +249,6 @@ void lctrInitActDisallowInitiate(void) /*************************************************************************************************/ /*! * \brief Notify host disallowing initiate cancel. - * - * \return None. */ /*************************************************************************************************/ void lctrInitActDisallowCancel(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master_ae.c index 35c0cccb71a..6efe08a6f3e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_init_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection state machine action routines. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection state machine action routines. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "lctr_int_init_master_ae.h" @@ -32,8 +33,6 @@ * \brief Shutdown active initiation operation. * * \param pExtInitCtx Extended scan context of the initiator. - * - * \return None. */ /*************************************************************************************************/ void lctrExtInitActShutdown(lctrExtScanCtx_t *pExtInitCtx) @@ -56,8 +55,6 @@ void lctrExtInitActShutdown(lctrExtScanCtx_t *pExtInitCtx) * \brief Terminated scan after host initiate disable. * * \param pExtInitCtx Extended scan context of the initiator. - * - * \return None. */ /*************************************************************************************************/ void lctrExtInitActScanTerm(lctrExtScanCtx_t *pExtInitCtx) @@ -68,13 +65,12 @@ void lctrExtInitActScanTerm(lctrExtScanCtx_t *pExtInitCtx) { if ((lctrMstExtInit.estConnPhys & (1 << i)) == 0) { - lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(lctrMstExtInitTbl[i].data.init.connHandle); + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(lctrMstExtInitTbl[i].data.init.connHandle); - if (pCtx->enabled == TRUE) + if (pConnCtx->enabled == TRUE) { /* Cleanup unused initiate PHY connection context. */ - SchRmRemove(lctrMstExtInitTbl[i].data.init.connHandle); - lctrFreeConnCtx(pCtx); + lctrSendConnMsg(pConnCtx, LCTR_CONN_INIT_CANCELED); } } } @@ -110,8 +106,6 @@ void lctrExtInitActScanTerm(lctrExtScanCtx_t *pExtInitCtx) * \brief Send disallow initiate host notification. * * \param pExtInitCtx Extended scan context of the initiator. - * - * \return None. */ /*************************************************************************************************/ void lctrExtInitActDisallowInitiate(lctrExtScanCtx_t *pExtInitCtx) @@ -126,8 +120,6 @@ void lctrExtInitActDisallowInitiate(lctrExtScanCtx_t *pExtInitCtx) * \brief Send disallow create connection cancel host notification. * * \param pExtInitCtx Extended scan context of the initiator. - * - * \return None. */ /*************************************************************************************************/ void lctrExtInitActDisallowCancel(lctrExtScanCtx_t *pExtInitCtx) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_pc.c new file mode 100644 index 00000000000..c8854126b2e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_pc.c @@ -0,0 +1,650 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connection power control state machine action routines. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_defs.h" +#include "lctr_int_conn.h" +#include "lctr_int_adv_slave.h" +#include "lctr_int_adv_master_ae.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "lmgr_api_conn.h" +#include "pal_radio.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_timer.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include +#include "lctr_int_pc.h" + +/*************************************************************************************************/ +/*! + * \brief Return the power control index of a phy bit. + * + * \param phyBit Phy bit. + * + * \return Power control phy index, or invalid if not valid. + */ +/*************************************************************************************************/ +static uint8_t lctrPhyBitToPclPhyIndex(uint8_t phyBit) +{ + uint8_t phyIndex; + for (phyIndex = LL_PC_PHY_1M; phyIndex <= LL_PC_PHY_TOTAL; phyIndex++) + { + if ((1 << (phyIndex - 1)) == phyBit) + { + return phyIndex; + } + } + return LL_PC_PHY_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Attempt a Tx power change. + * + * \param pCtx Connection context. + * \param phy PHY. + * \param delta Delta to current PHY txPower. + * + * \return Delta of the new txPower. + */ +/*************************************************************************************************/ +int8_t lctrAttemptTxPowerChange(lctrConnCtx_t *pCtx, uint8_t phy, int8_t delta) +{ + BbBleData_t * pBle = &pCtx->bleData; + + uint8_t option = (phy > LL_PHY_LE_CODED) ? BB_PHY_OPTIONS_BLE_S2 : BB_PHY_OPTIONS_BLE_S8; + if (phy > LL_PHY_LE_CODED) + { + phy = LL_PHY_LE_CODED; + } + + int8_t reqTxPower, curTxPower, newTxPower; + if (LCTR_GET_TXPOWER(pCtx, phy, option) == LL_PWR_CTRL_TXPOWER_UNAVAILABLE) + { + /* The current controller does not support this phy. */ + return 0; + } + else if (LCTR_GET_TXPOWER(pCtx, phy, option) == LL_PWR_CTRL_TXPOWER_UNMANAGED) + { + curTxPower = pLctrRtCfg->defTxPwrLvl; + reqTxPower = pLctrRtCfg->defTxPwrLvl + delta; + } + else + { + curTxPower = PalRadioGetActualTxPower(LCTR_GET_TXPOWER(pCtx, phy, option), FALSE); + reqTxPower = LCTR_GET_TXPOWER(pCtx, phy, option) + delta; + } + + /* Overflow catch condition. */ + if ((delta > 0) && + (reqTxPower < curTxPower)) + { + reqTxPower = LL_PWR_CTRL_TXPOWER_MAX; + } + + newTxPower = PalRadioIncreasePower(reqTxPower, delta); + + /* Update txPower. */ + LL_TRACE_INFO3("lctrAttemptTxPowerChange: Power change -> handle=%d phy=%d txPow=%d", LCTR_GET_CONN_HANDLE(pCtx), phy + (option == BB_PHY_OPTIONS_BLE_S2) ? 1 : 0, newTxPower); + LCTR_SET_TXPOWER(pCtx, phy + (((phy == LL_PHY_LE_CODED) && (option == BB_PHY_OPTIONS_BLE_S2)) ? 1 : 0), newTxPower); + + /* Update current txPower if necessary. */ + if (phy == pBle->chan.txPhy) + { + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, phy, option); + } + + return newTxPower - curTxPower; +} + +/*************************************************************************************************/ +/*! + * \brief Send peer power control request PDU. + * + * \param pCtx Connection context. + * \param delta Requested delta. + */ +/*************************************************************************************************/ +static void lctrSendPowerCtrlReqPdu(lctrConnCtx_t *pCtx, int8_t delta) +{ + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_PWR_CTRL_REQ_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + + /*** Assemble control PDU. ***/ + UINT8_TO_BSTREAM (pBuf, LL_PDU_PWR_CTRL_REQ); + UINT8_TO_BSTREAM (pBuf, (1 << (pCtx->reqPhy - 1))); + UINT8_TO_BSTREAM (pBuf, delta); + UINT8_TO_BSTREAM (pBuf, LCTR_GET_TXPOWER(pCtx, pCtx->reqPhy, pCtx->bleData.chan.initTxPhyOptions)); + + /*** Queue for transmit. ***/ + lctrTxCtrlPduQueue(pCtx, pPdu); + } + return; +} + +/*************************************************************************************************/ +/*! + * \brief Calculate Apr field for a power control response. + * + * \param pCtx Connection context. + * + * \return APR to be packed in response PDU. + */ +/*************************************************************************************************/ +static uint8_t lctrCalculateAprField(lctrConnCtx_t *pCtx) +{ + return LL_PWR_CTRL_APR_UNDEF; +} + +/*************************************************************************************************/ +/*! + * \brief Send peer power control response PDU. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +static void lctrSendPowerCtrlRspPdu(lctrConnCtx_t *pCtx) +{ + uint8_t *pPdu; + uint8_t option = (pCtx->reqPhy == LL_PC_PHY_CODED_S2) ? BB_PHY_OPTIONS_BLE_S2 : BB_PHY_OPTIONS_BLE_S8; + uint8_t txPhy = (pCtx->reqPhy < LL_PC_PHY_CODED_S2) ? pCtx->reqPhy : LL_PHY_LE_CODED; + int8_t txPower = LCTR_GET_TXPOWER(pCtx, txPhy, option); + + if ((pPdu = lctrTxCtrlPduAlloc(LL_PWR_CTRL_RSP_LEN)) != NULL) + { + uint8_t *pBuf = pPdu; + + /*** Assemble control PDU. ***/ + UINT8_TO_BSTREAM (pBuf, LL_PDU_PWR_CTRL_RSP); + UINT8_TO_BSTREAM (pBuf, lctrGetPowerLimits(txPower)); + UINT8_TO_BSTREAM (pBuf, pCtx->delta); + UINT8_TO_BSTREAM (pBuf, txPower); + UINT8_TO_BSTREAM (pBuf, lctrCalculateAprField(pCtx)); + + /*** Queue for transmit. ***/ + lctrTxCtrlPduQueue(pCtx, pPdu); + } + return; +} + +/*************************************************************************************************/ +/*! + * \brief Update action for power control processing. + * + * \param pCtx Connection Context. + */ +/*************************************************************************************************/ +void lctrStorePowerControlAction(lctrConnCtx_t *pCtx) +{ + pCtx->delta = pLctrConnMsg->pwrCtrlReq.delta; + pCtx->reqPhy = pLctrConnMsg->pwrCtrlReq.phy; + + LL_TRACE_INFO2("lctrStorePowerControlAction, PHY=%u delta=%u", pCtx->reqPhy, pCtx->delta); + + /* If the power wasn't managed before, start managing it now. */ + if (LCTR_GET_TXPOWER(pCtx, pCtx->reqPhy, BB_PHY_OPTIONS_BLE_S2) == LL_PWR_CTRL_TXPOWER_UNMANAGED) + { + LCTR_SET_TXPOWER(pCtx, pCtx->reqPhy, pLctrRtCfg->defTxPwrLvl); + + if (pCtx->reqPhy >= LL_PC_PHY_CODED_S8) + { + LCTR_SET_TXPOWER(pCtx, (pCtx->reqPhy == LL_PC_PHY_CODED_S8) ? LL_PC_PHY_CODED_S2 : LL_PC_PHY_CODED_S8, pLctrRtCfg->defTxPwrLvl); + } + } + + if (!pCtx->controllerInitRead && (pCtx->delta == 0)) + { + pCtx->readRemoteTxPower = TRUE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Send peer power control request. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrSendPeerPowerControlReq(lctrConnCtx_t *pCtx) +{ + lctrSendPowerCtrlReqPdu(pCtx, pCtx->delta); +} + +/*************************************************************************************************/ +/*! + * \brief Store peer power control request. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrStorePeerPowerControlReq(lctrConnCtx_t *pCtx) +{ + lctrPwrCtrlReq_t pld = lctrDataPdu.pld.pwrCtrlReq; + + pCtx->reqErrCode = LL_SUCCESS; + + uint8_t phyIdx = lctrPhyBitToPclPhyIndex(pld.phy); + + /* Verify txPower field is valid. */ + if (phyIdx == LL_PC_PHY_INVALID) + { + pCtx->reqErrCode = LL_ERROR_CODE_UNSUPPORTED_LMP_PARAM_VAL; + return; + } + + if (pld.txPower == LL_PWR_CTRL_TXPOWER_UNMANAGED) + { + pCtx->reqErrCode = LL_ERROR_CODE_INVALID_LMP_PARAMS; + return; + } + + /* Notify host of remote change if needed. */ + if ((pCtx->powerRptRemote) && + (pCtx->bleData.chan.rxPhy == phyIdx) && + (pCtx->peerTxPower != pld.txPower)) + { + lctrNotifyPowerReportInd(pCtx, LL_POWER_REPORT_REASON_REMOTE, phyIdx, pld.txPower, + lctrGetPowerLimits(pld.txPower), + pld.txPower - pCtx->peerTxPower); + } + + /* Update peer Tx power. */ + if (pCtx->bleData.chan.rxPhy == phyIdx) + { + pCtx->peerTxPower = pld.txPower; + + if ((pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNAVAILABLE) || + (pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNMANAGED)) + { + LL_TRACE_INFO1("lctrStorePeerPowerControlReq: txPower unmanaged or unavailable. Phy=%d", pld.phy); + } + else + { + LL_TRACE_INFO1("lctrStorePeerPowerControlReq: txPower=%d", pCtx->peerTxPower); + } + } + +#if (LL_ENABLE_TESTER == TRUE) + if (llTesterCb.powerLimits) + { + pCtx->delta = 0; + return; + } +#endif + + /* Attempt the txPower change, store delta for the response. */ + pCtx->delta = lctrAttemptTxPowerChange(pCtx, phyIdx, lctrDataPdu.pld.pwrCtrlReq.delta); + pCtx->reqPhy = phyIdx; + + /* Notify host of local change if needed. */ + if ((pCtx->delta != 0) && + (pCtx->powerRptLocal)) + { + uint8_t option = BB_PHY_OPTIONS_BLE_S8; + uint8_t phy = phyIdx; + + if (phy == LL_PC_PHY_CODED_S2) + { + option = BB_PHY_OPTIONS_BLE_S2; + phy = LL_PHY_LE_CODED; + } + + int8_t newTxPower = LCTR_GET_TXPOWER(pCtx, phy, option); + lctrNotifyPowerReportInd(pCtx, LL_POWER_REPORT_REASON_LOCAL, phyIdx, newTxPower, + lctrGetPowerLimits(newTxPower), + pCtx->delta); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send peer power control response. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrSendPeerPowerControlRsp(lctrConnCtx_t *pCtx) +{ + if (pCtx->reqErrCode == LL_SUCCESS) + { + lctrSendPowerCtrlRspPdu(pCtx); + + pCtx->peerReqRecvd = TRUE; + } + else + { + LL_TRACE_WARN0("lctrSendPeerPowerControlRsp: Peer sent invalid parameters for power control request."); + lctrSendRejectInd(pCtx, pCtx->reqErrCode, TRUE); + pCtx->reqErrCode = LL_SUCCESS; + } +} + +/*************************************************************************************************/ +/*! + * \brief Store peer power control response. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrStorePeerPowerControlRsp(lctrConnCtx_t *pCtx) +{ + lctrPwrCtrlRsp_t pld = lctrDataPdu.pld.pwrCtrlRsp; + + /* Notify host if needed. */ + if ((pCtx->powerRptRemote) && + (pCtx->peerTxPower != pld.txPower)) + { + lctrNotifyPowerReportInd(pCtx, LL_POWER_REPORT_REASON_REMOTE, pCtx->reqPhy, pld.txPower, + pld.limits, + pld.txPower - pCtx->peerTxPower); + } + + /* Update peer information, if needed. */ + if (pCtx->bleData.chan.rxPhy == pCtx->reqPhy) + { + pCtx->peerTxPower = pld.txPower; + pCtx->peerPwrLimits = pld.limits; + pCtx->peerApr[pCtx->reqPhy] = pld.apr; + + if ((pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNAVAILABLE) || + (pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNMANAGED)) + { + LL_TRACE_INFO1("lctrStorePeerPowerControlReq: txPower unmanaged or unavailable. Phy=%d", pCtx->reqPhy); + } + else + { + LL_TRACE_INFO1("lctrStorePeerPowerControlReq: txPower=%d", pCtx->peerTxPower); + + if (pCtx->controllerInitRead) + { + pCtx->controllerInitRead = FALSE; + } + + if (pCtx->monitoringState == LCTR_PC_MONITOR_PATH_LOSS) + { + if (pCtx->pclMonitorParam.pathLoss.initialPathLossRead) + { + pCtx->pclMonitorParam.pathLoss.initialPathLossRead = FALSE; + pCtx->pclMonitorParam.pathLoss.curZone = lctrCalcPathLossZone(pCtx); + lctrNotifyHostPathLossRpt(pCtx); + } + } + } + } + + /* Store delta for reporting. */ + pCtx->delta = pld.delta; + + LL_TRACE_INFO3("lctrStorePeerPowerControlRsp: peerTxPower=%d, peerPwrLimits=%d, peerApr=%d", pld.txPower, pld.limits, pld.apr); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of power report indication. + * + * \param pCtx Connection context. + * \param reason Reason this indication was sent. + * \param phy PHY. + * \param txPower Current txPower. + * \param limits Power limits. + * \param delta Delta from last txPower. + */ +/*************************************************************************************************/ +void lctrNotifyPowerReportInd(lctrConnCtx_t *pCtx, uint8_t reason, uint8_t phy, int8_t txPower, uint8_t limits, int8_t delta) +{ + const uint16_t handle = LCTR_GET_CONN_HANDLE(pCtx); + + LlPowerReportInd_t evt = + { + .hdr = + { + .param = handle, + .event = LL_TX_POWER_REPORTING_IND, + .status = LL_SUCCESS + }, + + .status = LL_SUCCESS, + .connHandle = handle, + .reason = reason, + .phy = phy, + .txPower = txPower, + .txPowerLimits = limits, + .delta = delta + }; + + LL_TRACE_INFO2("### LlEvent ### lctrNotifyPowerReportInd , handle=%u, reason=%d, status=LL_SUCCESS", handle, reason); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Send power change indication. + * + * \param pCtx Connection context. + * \param opcode PDU opcode. + * \param phyVal PHY. + * \param delta Delta from previous txPower. + * \param txPower Current txPower. + * \param phyChange The indication was caused by a PHY change. + */ +/*************************************************************************************************/ +static void lctrSendPowerChangePdu(lctrConnCtx_t *pCtx, uint8_t opcode, uint8_t phyVal, int8_t delta, int8_t txPower, bool_t phyChange) +{ + if (pCtx->peerReqRecvd == FALSE) /* Shall not be sent without a request received. */ + { + return; + } + + uint8_t *pPdu; + + if ((pPdu = lctrTxCtrlPduAlloc(LL_PWR_CHNG_IND_LEN)) != NULL) + { + bool_t seperateIndNeeded = FALSE; + uint8_t *pBuf = pPdu; + uint8_t phy = (1 << (phyVal - 1)); + + /* Attempt to pack coded ind in one ind. */ + if ((phy == LL_PC_CODED_S8_BIT) && (phyChange == TRUE)) + { + if (LCTR_GET_TXPOWER(pCtx, LL_PHY_LE_CODED, BB_PHY_OPTIONS_BLE_S2) == LCTR_GET_TXPOWER(pCtx, LL_PHY_LE_CODED, BB_PHY_OPTIONS_BLE_S8)) + { + phy |= LL_PC_CODED_S2_BIT; + } + else + { + seperateIndNeeded = TRUE; + } + } + + /*** Assemble control PDU. ***/ + UINT8_TO_BSTREAM (pBuf, opcode); + UINT8_TO_BSTREAM (pBuf, phy); + UINT8_TO_BSTREAM (pBuf, lctrGetPowerLimits(txPower)); + UINT8_TO_BSTREAM (pBuf, delta); + UINT8_TO_BSTREAM (pBuf, txPower); + + /*** Queue for transmit. ***/ + lctrTxCtrlPduQueue(pCtx, pPdu); + + /* For coded, we need to send S2 txPower as well. */ + if (seperateIndNeeded) + { + txPower = LCTR_GET_TXPOWER(pCtx, LL_PHY_LE_CODED, BB_PHY_OPTIONS_BLE_S2); + pBuf = pPdu + 1; + UINT8_TO_BSTREAM (pBuf, LL_PC_CODED_S2_BIT); + UINT8_TO_BSTREAM (pBuf, lctrGetPowerLimits(txPower)); + UINT8_TO_BSTREAM (pBuf, delta); + UINT8_TO_BSTREAM (pBuf, txPower); + + /*** Queue for transmit. ***/ + lctrTxCtrlPduQueue(pCtx, pPdu); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Send power control indication. + * + * \param pCtx Connection context. + * \param phy PHY. + * \param delta Delta from previous txPower. + * \param txPower Current txPower. + * \param phyChange The indication was a result of a PHY change. + */ +/*************************************************************************************************/ +void lctrSendPowerChangeInd(lctrConnCtx_t *pCtx, uint8_t phy, int8_t delta, int8_t txPower, bool_t phyChange) +{ + lctrSendPowerChangePdu(pCtx, LL_PDU_PWR_CHNG_IND, phy, delta, txPower, phyChange); +} + +/*************************************************************************************************/ +/*! + * \brief Store peer power indication. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrStorePeerPowerInd(lctrConnCtx_t *pCtx) +{ + lctrPwrChngInd_t * pPdu = &lctrDataPdu.pld.pwrChngInd; + LL_TRACE_INFO3("lctrStorePeerPowerInd: Phy=%d Delta=%d txPower=%d", pPdu->phy, pPdu->delta, pPdu->txPower); + + if (pPdu->phy & (1 << (pCtx->bleData.chan.rxPhy - 1))) + { + if ((pCtx->peerTxPower != pPdu->txPower) && + (pCtx->powerRptRemote)) + { + lctrNotifyPowerReportInd(pCtx, LL_POWER_REPORT_REASON_REMOTE, pCtx->bleData.chan.rxPhy, pPdu->txPower, + pPdu->limits, + pPdu->txPower - pCtx->peerTxPower); + } + + if (pPdu->phy == pCtx->bleData.chan.rxPhy) + { + pCtx->peerTxPower = pPdu->txPower; + + if ((pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNAVAILABLE) || + (pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNMANAGED)) + { + LL_TRACE_INFO1("lctrStorePeerPowerInd: txPower unmanaged or unavailable. Phy=%d", pPdu->phy); + } + else + { + LL_TRACE_INFO1("lctrStorePeerPowerInd: txPower=%d", pCtx->peerTxPower); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Send peer power indication response (Included for state machine conformance). + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrSendPeerPowerRsp(lctrConnCtx_t *pCtx) +{ + /* No need to reply to power change indications. */ + return; +} + +/*************************************************************************************************/ +/*! + * \brief Power monitoring action function + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrAutoPowerMonitorAct(lctrConnCtx_t *pCtx) +{ + if (!(pCtx->usedFeatSet & LL_FEAT_POWER_CONTROL_REQUEST)) + { + pCtx->monitoringState = LCTR_PC_MONITOR_DISABLED; + return; + } + + if (lmgrCb.opModeFlags & LL_OP_MODE_DISABLE_POWER_MONITOR) + { + return; + } + + int8_t sendReqDelta = 0; + + if ((pCtx->rssi < pCtx->pclMonitorParam.autoMonitor.lowThreshold) || + (pCtx->lastRxStatus != BB_STATUS_SUCCESS)) + { + pCtx->pclMonitorParam.autoMonitor.curTimeSpent++; + + if (pCtx->pclMonitorParam.autoMonitor.curTimeSpent >= pCtx->pclMonitorParam.autoMonitor.minTimeSpent) + { + if (!(pCtx->peerPwrLimits & LL_PWR_CONTROL_LIMIT_MAX_BIT)) + { + LL_TRACE_INFO1("RSSI too low, requesting increase in power. phy=%u", pCtx->bleData.chan.rxPhy); + sendReqDelta = pCtx->pclMonitorParam.autoMonitor.requestVal; + } + pCtx->pclMonitorParam.autoMonitor.curTimeSpent = 0; + } + } + else if (pCtx->rssi > pCtx->pclMonitorParam.autoMonitor.highThreshold) + { + pCtx->pclMonitorParam.autoMonitor.curTimeSpent++; + + if (pCtx->pclMonitorParam.autoMonitor.curTimeSpent >= pCtx->pclMonitorParam.autoMonitor.minTimeSpent) + { + if (!(pCtx->peerPwrLimits & LL_PWR_CONTROL_LIMIT_MIN_BIT)) + { + LL_TRACE_INFO1("RSSI too high, requesting decrease in power. phy=%u", pCtx->bleData.chan.rxPhy); + sendReqDelta = -(pCtx->pclMonitorParam.autoMonitor.requestVal); + } + pCtx->pclMonitorParam.autoMonitor.curTimeSpent = 0; + } + } + else + { + pCtx->pclMonitorParam.autoMonitor.curTimeSpent = 0; + } + + if (sendReqDelta != 0) + { + uint8_t reqPhy = pCtx->bleData.chan.rxPhy + (((pCtx->bleData.chan.rxPhy == BB_PHY_BLE_CODED) && (pCtx->bleData.chan.initTxPhyOptions == BB_PHY_OPTIONS_BLE_S2)) ? 1 : 0); + + lctrMsgPwrCtrlReq_t *pMsg; + if ((pMsg = (lctrMsgPwrCtrlReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = LCTR_GET_CONN_HANDLE(pCtx); + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_PWR_CTRL_REQ; + pMsg->delta = sendReqDelta; + pMsg->phy = reqPhy; + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_phy.c index 6a5f91e22a6..7c5b60deec5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_act_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller PHY features action routines. + * \file + * + * \brief Link layer controller PHY features action routines. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,8 +35,6 @@ * \brief Store PHY update request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStoreHostPhyUpdate(lctrConnCtx_t *pCtx) @@ -53,8 +52,6 @@ void lctrStoreHostPhyUpdate(lctrConnCtx_t *pCtx) * \brief Store PHY update request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStorePeerPhyReq(lctrConnCtx_t *pCtx) @@ -67,8 +64,6 @@ void lctrStorePeerPhyReq(lctrConnCtx_t *pCtx) * \brief Store PHY update indication. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrStorePeerPhyUpdateInd(lctrConnCtx_t *pCtx) @@ -102,8 +97,6 @@ void lctrStorePeerPhyUpdateInd(lctrConnCtx_t *pCtx) * \param opcode Opcode to send in PDU. * \param txPhys Transmitter PHYs. * \param rxPhys Receiver PHYs. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendPhyPdu(lctrConnCtx_t *pCtx, uint8_t opcode, uint8_t txPhys, uint8_t rxPhys) @@ -134,8 +127,6 @@ static void lctrSendPhyPdu(lctrConnCtx_t *pCtx, uint8_t opcode, uint8_t txPhys, * \param pCtx Connection context. * \param txPhys Transmitter PHYs. * \param rxPhys Receiver PHYs. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPhyReqPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys) @@ -157,8 +148,6 @@ void lctrSendPhyReqPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys) * \param pCtx Connection context. * \param txPhys Transmitter PHYs. * \param rxPhys Receiver PHYs. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPhyRspPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys) @@ -173,8 +162,6 @@ void lctrSendPhyRspPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys) * \param pCtx Connection context. * \param txPhys Transmitter PHYS. * \param rxPhys Receiver PHYS. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPhyUpdateIndPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys) @@ -233,8 +220,6 @@ void lctrSendPhyUpdateIndPdu(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys * * \param pCtx Connection context. * \param status Status. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostPhyUpdateInd(lctrConnCtx_t *pCtx, uint8_t status) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int.h index d93a55f00a3..055322511e3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,10 +26,11 @@ #define LCTR_INT_H #include "lctr_api.h" -#include "ll_defs.h" #include "lmgr_api.h" +#include "ll_defs.h" #include "ll_math.h" #include "util/crc32.h" +#include "pal_bb.h" #if (LL_ENABLE_TESTER) #include "ll_tester_api.h" @@ -44,73 +46,76 @@ extern "C" { **************************************************************************************************/ /*! \brief Minimum delay between connect indication and data channel in CONNECT_IND units. */ -#define LCTR_DATA_CHAN_DLY 1 /* 1.25 ms */ +#define LCTR_DATA_CHAN_DLY 1 /* 1.25 ms */ /*! \brief Minimum delay between auxiliary connect request and data channel using uncoded PHY in CONNECT_REQ units. */ -#define LCTR_DATA_CHAN_DLY_AUX_UNCODED 2 /* 2.5 ms */ +#define LCTR_DATA_CHAN_DLY_AUX_UNCODED 2 /* 2.5 ms */ /*! \brief Minimum delay between auxiliary connect request and data channel using coded PHY in CONNECT_REQ units. */ -#define LCTR_DATA_CHAN_DLY_AUX_CODED 3 /* 3.75 ms */ +#define LCTR_DATA_CHAN_DLY_AUX_CODED 3 /* 3.75 ms */ /*! \brief Convert connect indication ticks to scheduler ticks. */ -#define LCTR_CONN_IND_TICKS(x) ((x) * (1250 / LL_BLE_US_PER_TICK)) +#define LCTR_CONN_IND_TICKS(x) ((x) * (1250 / LL_BLE_US_PER_TICK)) /*! \brief Convert connect indication ticks to milliseconds (no divide, rounds up). */ -#define LCTR_CONN_IND_MS(x) ((x) + ((x) >> 2) + (((x) & 3) ? 1 : 0)) +#define LCTR_CONN_IND_MS(x) ((x) + ((x) >> 2) + (((x) & 3) ? 1 : 0)) /*! \brief Convert connect indication ticks to microseconds. */ -#define LCTR_CONN_IND_US(x) ((x) * 1250) +#define LCTR_CONN_IND_US(x) ((x) * 1250) /*! \brief Convert connect indication timeout ticks to milliseconds. */ -#define LCTR_CONN_IND_TO_MS(x) ((x) * 10) +#define LCTR_CONN_IND_TO_MS(x) ((x) * 10) /*! \brief Convert microseconds to connection indication ticks. */ -#define LCTR_US_TO_CONN_IND(x) LL_MATH_DIV_1250(x) +#define LCTR_US_TO_CONN_IND(x) LL_MATH_DIV_1250(x) /*! \brief Convert BLE protocol ticks to microseconds. */ -#define LCTR_BLE_TO_US(x) ((x) * LL_BLE_US_PER_TICK) +#define LCTR_BLE_TO_US(x) ((x) * LL_BLE_US_PER_TICK) -/*! \brief Convert periodic interval units to microseconds. */ -#define LCTR_PER_INTER_TO_US(x) ((x) * 1250) +/*! \brief Convert periodic interval milliseconds to microseconds. */ +#define LCTR_PER_INTER_TO_US(x) ((x) * 1250) /*! \brief Convert periodic interval microseconds to milliseconds. */ -#define LCTR_PER_INTER_TO_MS(x) LL_MATH_DIV_1250(x) +#define LCTR_PER_INTER_TO_MS(x) LL_MATH_DIV_1250(x) /*! \brief Convert periodic sync timeout unit to milliseconds. */ -#define LCTR_PER_SYNC_TIMEOUT_TO_MS(x) ((x) * 10) +#define LCTR_PER_SYNC_TIMEOUT_TO_MS(x) ((x) * 10) /*! \brief Convert isochronous interval to microseconds. */ -#define LCTR_ISO_INT_TO_US(x) ((x) * 1250) +#define LCTR_ISO_INT_TO_US(x) ((x) * 1250) /*! \brief Fast termination supervision multiplier. */ -#define LCTR_FAST_TERM_CNT 6 +#define LCTR_FAST_TERM_CNT 6 /*! \brief Duration of a advertising packet in microseconds. */ -#define LCTR_ADV_PKT_1M_US(len) ((LL_PREAMBLE_LEN_1M + LL_AA_LEN + LL_ADV_HDR_LEN + len + LL_CRC_LEN) << 3) +#define LCTR_ADV_PKT_1M_US(len) ((LL_PREAMBLE_LEN_1M + LL_AA_LEN + LL_ADV_HDR_LEN + len + LL_CRC_LEN) << 3) /*! \brief Duration of a connection indication packet in microseconds. */ -#define LCTR_CONN_IND_PKT_1M_US LCTR_ADV_PKT_1M_US(LL_CONN_IND_PDU_LEN) +#define LCTR_CONN_IND_PKT_1M_US LCTR_ADV_PKT_1M_US(LL_CONN_IND_PDU_LEN) /*! \brief Extra area in ADVB buffer. */ -#define LCTR_ADVB_BUF_EXTRA_SIZE 6 +#define LCTR_ADVB_BUF_EXTRA_SIZE 6 /*! \brief Size for ADVB buffer allocation. */ -#define LCTR_ADVB_BUF_SIZE (WSF_MAX(BB_FIXED_ADVB_PKT_LEN, LL_ADVB_MAX_LEN) + LCTR_ADVB_BUF_EXTRA_SIZE) +#define LCTR_ADVB_BUF_SIZE (WSF_MAX(BB_FIXED_ADVB_PKT_LEN, LL_ADVB_MAX_LEN) + LCTR_ADVB_BUF_EXTRA_SIZE) /*! \brief RSSI offset of extra data in ADVB buffer. */ -#define LCTR_ADVB_BUF_OFFSET_RSSI ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 0) +#define LCTR_ADVB_BUF_OFFSET_RSSI ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 0) /*! \brief RPA offset of extra data in ADVB buffer. */ -#define LCTR_ADVB_BUF_OFFSET_RX_RPA ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 1) +#define LCTR_ADVB_BUF_OFFSET_RX_RPA ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 1) /*! \brief CRC offset of extra data in ADVB buffer. */ -#define LCTR_ADVB_BUF_OFFSET_CRC ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 2) +#define LCTR_ADVB_BUF_OFFSET_CRC ((LCTR_ADVB_BUF_SIZE - LCTR_ADVB_BUF_EXTRA_SIZE) + 2) /*! \brief LCTR Maximum span of scheduler elements. */ -#define LCTR_SCH_MAX_SPAN 0x80000000 +#define LCTR_SCH_MAX_SPAN ((BbGetBbTimerBoundaryUs() >> 1) + 1) /*! \brief LCTR Maximum value for sleep clock accuracy. */ -#define LCTR_MAX_SCA 7 +#define LCTR_MAX_SCA 7 + +/*! \brief Change supervision timeout value to us. */ +#define LCTR_SUP_TIMEOUT_VAL_TO_US(x) (x * 10000) /************************************************************************************************** Data Types @@ -128,6 +133,9 @@ typedef void (*LctrEvtHdlr_t)(void); /*! \brief Reservation manager callback signature. */ typedef void (*LctrRmCback_t)(uint32_t rsvnOffs[], uint32_t refTime); +/*! \brief Channel class update handler call signature. */ +typedef uint8_t (*lctrChClassHdlr_t)(uint64_t chanMap); + /************************************************************************************************** Globals **************************************************************************************************/ @@ -137,13 +145,18 @@ extern LctrMsgDisp_t lctrMsgDispTbl[LCTR_DISP_TOTAL]; extern LctrEvtHdlr_t lctrEventHdlrTbl[LCTR_EVENT_TOTAL]; extern lctrMsgHdr_t *pLctrMsg; extern const uint16_t scaPpmTbl[]; +extern bool_t lctrResetEnabled; /************************************************************************************************** Functions **************************************************************************************************/ +/* Initialization. */ +void lctrRegisterChClassHandler(lctrChClassHdlr_t cback); + /* Helper routines. */ uint32_t lctrComputeAccessAddr(void); +uint32_t lctrComputeSeedAccessAddr(void); uint8_t lctrComputeHopInc(void); uint8_t lctrPeriodicSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t eventCounter); void lctrPeriodicBuildRemapTable(lmgrChanParam_t *pChanParam); @@ -177,6 +190,52 @@ static inline uint16_t lctrCalcDID(const uint8_t *pBuf, uint16_t len) return CalcCrc32(LlMathRandNum(), len, pBuf); } +/*************************************************************************************************/ +/*! + * \brief Convert PHYS bit to PHY. + * + * \param physBit PHYS bit. + * + * \return PHY. + */ +/*************************************************************************************************/ +static inline PalBbPhy_t lctrPhysBitToPhy(uint8_t physBit) +{ + switch (physBit) + { + default: + case LL_PHYS_LE_1M_BIT: + return BB_PHY_BLE_1M; + case LL_PHYS_LE_2M_BIT: + return BB_PHY_BLE_2M; + case LL_PHYS_LE_CODED_BIT: + return BB_PHY_BLE_CODED; + } +} + +/*************************************************************************************************/ +/*! + * \brief Convert PHY to PHYS bit. + * + * \param phy PHY. + * + * \return PHYS bit. + */ +/*************************************************************************************************/ +static inline uint8_t lctrPhyToPhysBit(uint8_t phy) +{ + switch (phy) + { + default: + case BB_PHY_BLE_1M: + return LL_PHYS_LE_1M_BIT; + case BB_PHY_BLE_2M: + return LL_PHYS_LE_2M_BIT; + case BB_PHY_BLE_CODED: + return LL_PHYS_LE_CODED_BIT; + } +} + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_ae.h index 05708f3eb17..afa53fb4775 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_ae.h @@ -1,24 +1,26 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Extended advertising common header file * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Extended advertising common header file */ /*************************************************************************************************/ #ifndef LCTR_INT_ADV_AE_H @@ -26,65 +28,49 @@ #include "ll_defs.h" #include "lctr_api.h" +#include "lctr_api_adv_acad.h" #include #ifdef __cplusplus extern "C" { #endif -/*! \brief Acad parameter indicies */ +/*! \brief ACAD parameter indices */ enum { LCTR_ACAD_ID_CHAN_MAP_UPDATE, + LCTR_ACAD_ID_BIG_INFO, - /* Total number of Acad IDs. */ + /* Total number of ACAD IDs. */ LCTR_ACAD_NUM_ID, /* Invalid ID type. */ LCTR_ACAD_INVALID_ID = 0xFF }; -/*! \brief Acad states */ +/*! \brief ACAD states */ enum { LCTR_ACAD_STATE_DISABLED = 0, LCTR_ACAD_STATE_ENABLED, - LCTR_ACAD_STATE_TOTAL }; -/*! \brief Acad Common events */ +/*! \brief ACAD Common events */ enum { LCTR_ACAD_COMM_MSG_START, LCTR_ACAD_COMM_MSG_FINISH, - LCTR_ACAD_COMM_MSG_TOTAL, - LCTR_ACAD_COMM_MSG_INVALID = 0xFF }; -/*! \brief Acad header */ -typedef struct -{ - uint8_t state; /* State of Acad. */ - uint8_t opcode; /* Opcode of Acad. */ - uint8_t len; /* Length of Acad data field. */ -} lctrAcadHdr_t; - -/*! \brief Acad data field for channel map update */ -typedef struct -{ - lctrAcadHdr_t hdr; /* Acad header. */ - uint64_t chanMask; /* Channel mask for the update. */ - uint16_t instant; /* Instant for the update. */ -} lctrAcadChanMapUpd_t; - -/*! \brief Generic Acad packet. */ +/*! \brief Generic ACAD packet. */ typedef union { - lctrAcadHdr_t hdr; /* Acad header. */ - lctrAcadChanMapUpd_t chanMapUpdate; /* Channel map update. */ + LctrAcadHdr_t hdr; /*!< ACAD header. */ + LctrAcadChanMapUpd_t chanMapUpdate; /*!< Channel map update. */ + LctrAcadBigInfo_t bigInfo; /*!< BIG info. */ } lctrAcadParam_t; #ifdef __cplusplus diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master.h index 93782d1e604..ce5ef69cb54 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller scanning master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -38,8 +39,8 @@ extern "C" { Macros **************************************************************************************************/ -/*! \brief Minimum amount of time required for scanning, to be same as minimum time in BB(1528us). */ -#define LCTR_MIN_SCAN_USEC BB_SCAN_GUARD_US +/*! \brief Minimum amount of time required for scanning, to cover ADV + SCAN REQ + SCAN RSP. */ +#define LCTR_MIN_SCAN_USEC BB_MIN_SCAN_US /************************************************************************************************** Constants @@ -80,7 +81,7 @@ typedef struct wsfQueue_t rxAdvbQ; /*!< Receive ADVB queue. */ wsfQueue_t rxDirectAdvbQ; /*!< Receive direct ADVB queue. */ - uint32_t scanWinStart; /*!< Scan window origin. */ + uint32_t scanWinStartUsec; /*!< Scan window origin in microseconds. */ lmgrScanParam_t scanParam; /*!< Scan parameters. */ @@ -100,7 +101,6 @@ typedef struct uint64_t localRpa; /*!< Local RPA. */ uint16_t connHandle; /*!< Connection handle. */ uint16_t connInterval; /*!< Connection interval. */ - uint32_t firstCeDue; /*!< First CE due time. */ bool_t connBodLoaded; /*!< Connection BOD loaded flag. */ uint8_t usedChSel; /*!< Used channel selection. */ } init; /*!< Initiation specific data. */ @@ -144,7 +144,7 @@ void lctrMstDiscoverAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAd bool_t lctrMstScanReqTxCompHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); bool_t lctrMstScanRspRxCompHandler(BbOpDesc_t *pOp, const uint8_t *pRspBuf); -/* Action routines. */ +/* Action routines */ void lctrScanActDiscover(void); void lctrScanActShutdown(void); void lctrScanActScanCnf(void); @@ -158,15 +158,15 @@ void lctrInitActInitiate(void); void lctrInitActConnect(void); void lctrInitActShutdown(void); -/* Helper routines. */ +/* Helper routines */ void lctrScanCleanup(lctrMstScanCtx_t *pCtx); void lctrScanNotifyHostInitiateError(uint8_t reason, uint8_t peerAddrType, uint64_t peerAddr); -/* Channel. */ +/* Channel */ uint8_t lctrScanChanSelectInit(uint8_t chanMap); uint8_t lctrScanChanSelectNext(uint8_t chanIdx, uint8_t chanMap); -/* Advertising report filtering. */ +/* Advertising report filtering */ void lctrAdvRptEnable(lctrAdvRptFilt_t *pAdvFilt, bool_t filtEna); void lctrAdvRptGenerateLegacyHash(uint64_t *pHash, uint8_t addrType, uint64_t addr, uint8_t eventType); void lctrAdvRptGenerateExtHash(uint64_t *pHash, uint8_t addrType, uint64_t addr, uint8_t eventType, diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master_ae.h index 91090a09920..a69af4b68b9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_master_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller extended scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller extended scanning master interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,13 +43,22 @@ extern "C" { **************************************************************************************************/ /*! \brief Resolve the extended scan handle from the context pointer. */ -#define LCTR_GET_EXT_SCAN_HANDLE(pCtx) (pCtx - lctrMstExtScanTbl) +#define LCTR_GET_EXT_SCAN_HANDLE(pCtx) (pCtx->handle) + +/*! \brief Resolve the extended scan context from the handle. */ +#define LCTR_GET_EXT_SCAN_CTX(h) (lctrMstExtScanTbl[h]) /*! \brief Resolve the periodic scanning handle from the context pointer. */ #define LCTR_GET_PER_SCAN_HANDLE(pCtx) (pCtx - lctrMstPerScanTbl) +/*! \brief Get topology manager handle from the periodic scanning context pointer. */ +#define LCTR_GET_PER_SCAN_TM_HANDLE(pCtx) (LL_MAX_CONN + LCTR_GET_PER_SCAN_HANDLE(pCtx)) + /*! \brief Resolve the periodic scanning context from the handle. */ -#define LCTR_GET_PER_SCAN_CTX(h) &(lctrMstPerScanTbl[h]) +#define LCTR_GET_PER_SCAN_CTX(h) (&lctrMstPerScanTbl[h]) + +/*! \brief Valid active scan mask. */ +#define LCTR_VALID_ACTIVE_SCAN_MASK ((1 << LCTR_SCAN_PHY_1M) | (1 << LCTR_SCAN_PHY_CODED)) /************************************************************************************************** Constants @@ -121,9 +131,11 @@ typedef struct uint8_t state; /*!< Scan state. */ bool_t selfTerm; /*!< Self-termination flag. */ bool_t shutdown; /*!< Client initiated shutdown flag. */ - uint32_t scanWinStart; /*!< Scan window origin. */ + bool_t bodAborted; /*!< True if BOD was aborted by scheduler. */ + uint32_t scanWinStartUsec; /*!< Scan window origin in microseconds. */ LlScanParam_t scanParam; /*!< Scan parameters. */ /* N.B. Scan parameters must persist after initiate. */ + uint8_t handle; /*!< Scan handle. */ union { struct @@ -150,9 +162,7 @@ typedef struct uint64_t localRpa; /*!< Local RPA. */ uint16_t connHandle; /*!< Connection handle. */ uint16_t connInterval; /*!< Connection interval. */ - uint32_t firstCeDue; /*!< First CE due time. */ - uint32_t scanWinStart; /*!< Scan window origin. */ - bool_t connBodLoaded; /*!< Connection BOD loaded flag. */ + uint32_t scanWinStartUsec; /*!< Scan window origin in microseconds. */ bool_t isLegacy; /*!< TRUE if legacy advertising PDU is received. */ uint8_t usedChSel; /*!< Used channel selection. */ uint8_t filtPolicy; /*!< Initiate filter policy. */ @@ -188,7 +198,7 @@ typedef struct { /* State. */ uint8_t enaPhys; /*!< Enabled PHYs. */ - bool_t scanTermByHost; /*!< Host initiated scan disable. */ + uint8_t scanTermByHost; /*!< Times host initiated scan disable. */ uint32_t nextScanWinStart; /*!< Next scan window origin. */ /* Report */ @@ -203,6 +213,17 @@ typedef struct wsfTimer_t tmrScanPer; /*!< Scan period timer. */ } lctrExtScanCtrlBlk_t; +/*! \brief Active extended scanning context. */ +typedef struct +{ + uint8_t scanMask; /*!< Mask for active scan contexts. */ + uint8_t scanIndex; /*!< Index of the active scan context. */ + uint8_t bodSchMask; /*!< Mask for BOD scheduling for each phy. */ +} lctrActiveExtScan_t; + +/*! \brief Termination event handler call signature. */ +typedef void (*lctrTermHdlr_t)(uint16_t syncHandle); + /*! \brief Periodic scanning context. */ typedef struct { @@ -215,6 +236,7 @@ typedef struct bool_t repDisabled; /*!< Reporting disabled. */ bool_t bodAborted; /*!< Tue if periodic scan BOD was aborted. */ uint8_t createDispId; /*!< Dispatcher id to tell if periodic sync was created or transferred. */ + lctrTermHdlr_t termCback; /*!< Termination callback. */ /* Report handling. */ LlPerAdvReportInd_t advRpt; /*!< Periodic advertising report. */ @@ -227,18 +249,17 @@ typedef struct /* Peer periodic advertising parameters */ uint16_t eventCounter; /*!< Connection event counter. */ - uint32_t perInter; /*!< Periodic scanning interval in BB ticks. */ + uint32_t perInterUsec; /*!< Periodic scanning interval in microseconds. */ uint8_t sca; /*!< Sleep clock accuracy. */ - uint32_t skipInter; /*!< Skip interval in BB ticks. */ + uint32_t skipInterUsec; /*!< Skip interval in microseconds. */ uint32_t minDurUsec; /*!< Minimum required duration in microseconds. */ uint32_t rxSyncDelayUsec; /*!< Receive timeout in microseconds. */ - uint32_t lastAnchorPoint; /*!< Last anchor point in BB tick. */ + uint32_t lastAnchorPointUsec;/*!< Last anchor point in microseconds. */ uint16_t lastActiveEvent; /*!< Last active event counter. */ uint16_t initEventCounter; /*!< Initial event counter received from sync_info. */ - /* Acad control block */ - /* Note: for now, the acad type only applies to the periodic context. */ - lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< Acad control block array. */ + /* ACAD */ + lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< ACAD control block array. */ /* Local periodic scanning parameters */ uint16_t skip; /*!< Skip. */ @@ -249,7 +270,6 @@ typedef struct /* RF parameters */ int8_t rssi; /*!< RSSI. */ - lmgrChanParam_t chanParam; /*!< Channel parameters. */ /* Supervision */ @@ -279,19 +299,19 @@ typedef struct lctrPerScanCtx_t *pPerScanCtx; /*!< Current synchronous context. */ } lctrPerCreateSyncCtrlBlk_t; -/*! \brief Acad message header. */ +/*! \brief ACAD message header. */ typedef struct { uint16_t eventCtr; /*!< Current event counter. */ uint16_t skip; /*!< Skip amount. */ - uint8_t acadId; /*!< Acad ID being processed. */ + uint8_t acadId; /*!< ACAD ID being processed. */ uint16_t handle; /*!< Active Handle. */ } lctrAcadMsgHdr_t; -/*! \brief Acad message generic type. */ +/*! \brief ACAD message generic type. */ typedef union { - lctrAcadMsgHdr_t hdr; /*!< Header of an Acad Msg. */ + lctrAcadMsgHdr_t hdr; /*!< Header of an ACAD message. */ } lctrAcadMsg_t; /*! \brief Periodic sync transfer state context. */ @@ -312,8 +332,9 @@ typedef struct Globals **************************************************************************************************/ -extern lctrExtScanCtx_t lctrMstExtScanTbl[LCTR_SCAN_PHY_TOTAL]; +extern lctrExtScanCtx_t * lctrMstExtScanTbl[LCTR_SCAN_PHY_TOTAL]; extern lctrExtScanCtrlBlk_t lctrMstExtScan; +extern lctrActiveExtScan_t lctrActiveExtScan; extern lctrPerCreateSyncCtrlBlk_t lctrPerCreateSync; extern lctrPerTransferSyncCtrlBlk_t lctrPerTransferSync; extern lctrPerScanCtx_t lctrMstPerScanTbl[LL_MAX_PER_SCAN]; @@ -333,7 +354,7 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle); /* ISR: Discovery packet handlers */ bool_t lctrMstDiscoverRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); -void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); +void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); bool_t lctrMstDiscoverRxAuxScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBuf); uint32_t lctrMstDiscoverRxAuxChainHandler(BbOpDesc_t *pOp, const uint8_t *pChainBuf); @@ -343,6 +364,7 @@ bool_t lctrMstDiscoverTxLegacyScanReqHandler(BbOpDesc_t *pOp, const uint8_t *pRe bool_t lctrMstDiscoverRxLegacyScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBuf); /* ISR: Discovery BOD handlers */ void lctrMstExtDiscoverEndOp(BbOpDesc_t *pOp); +void lctrMstExtDiscoverAbortOp(BbOpDesc_t *pOp); void lctrMstAuxDiscoverEndOp(BbOpDesc_t *pOp); void lctrMstPerScanEndOp(BbOpDesc_t *pOp); void lctrMstPerScanAbortOp(BbOpDesc_t *pOp); @@ -353,7 +375,9 @@ bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdv void lctrExtScanActDiscover(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActShutdown(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActScanCnf(lctrExtScanCtx_t *pExtScanCtx); +void lctrExtScanHostDisable(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActDisallowScan(lctrExtScanCtx_t *pExtScanCtx); +void lctrExtScanActHostEnable(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActScanTerm(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActSelfTerm(lctrExtScanCtx_t *pExtScanCtx); void lctrExtScanActUpdateDiscover(lctrExtScanCtx_t *pExtScanCtx); @@ -444,8 +468,6 @@ static inline uint8_t lctrConvertAuxPtrPhyToBbPhy(uint8_t auxPtrPhy) * \param pAuxPtr Auxiliary Pointer. * \param pOffsetUsec Return auxiliary offset in microseconds. * \param pSyncDelayUsec Return synchronization delay in microseconds. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrMstComputeAuxOffset(lctrAuxPtr_t *pAuxPtr, uint32_t *pOffsetUsec, uint32_t *pSyncDelayUsec) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave.h index 179af533f43..87cc8c18062 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller advertising slave interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller advertising slave interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -79,7 +80,7 @@ typedef struct uint8_t usedChSel; /*!< Used channel selection. */ BbOpDesc_t advBod; /*!< Advertising BOD. */ BbBleData_t bleData; /*!< BLE BB operation data. */ - uint32_t reqEndTs; /*!< Last received request end of packet timestamp. */ + uint32_t reqEndTsUsec; /*!< Last received request end of packet timestamp in microseconds. */ /* Scan buffer (placed here to 32-bit align) */ uint8_t scanRspBuf[LL_ADVB_MAX_LEN]; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave_ae.h index 82124a47ea2..1dd7f971b1b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_adv_slave_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller slave extended advertising interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller slave extended advertising interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -65,6 +66,12 @@ extern "C" { /*! \brief Get reservation manager handle for periodic ADV from the context pointer. */ #define LCTR_GET_PER_RM_HANDLE(pAdvSet) (LL_MAX_CONN + LCTR_GET_EXT_ADV_INDEX(pAdvSet)) +/*! \brief Call signature for slave ACAD BIG related function. */ +typedef void (*lctrAcadBigHdlr_t)(uint8_t advHandle); + +/*! \brief Call signature for AdvSet Remove event handler. */ +typedef void (*lctrRemoveHdlr_t)(uint8_t advHandle); + /************************************************************************************************** Constants **************************************************************************************************/ @@ -96,22 +103,22 @@ enum /*! \brief Extended advertising parameters. */ typedef struct { - uint16_t advEventProp; /*!< Advertising Event Properties. */ - uint32_t priAdvInterMin; /*!< Primary Advertising Interval Minimum. */ - uint32_t priAdvInterMax; /*!< Primary Advertising Interval Maximum. */ - uint32_t priAdvTermCntDown; /*!< Primary Advertising termination count down. */ - uint64_t peerAddr; /*!< Peer Address. */ - uint8_t priAdvChanMap; /*!< Primary Advertising Channel Map. */ - uint8_t ownAddrType; /*!< Own Address Type. */ - uint8_t peerAddrType; /*!< Peer Address Type. */ - uint8_t advFiltPolicy; /*!< Advertising Filter Policy. */ - int8_t advTxPwr; /*!< Advertising Tx Power. */ - uint8_t priAdvPhy; /*!< Primary Advertising PHY. */ - uint8_t secAdvMaxSkip; /*!< Secondary Advertising Maximum Skip. */ - uint8_t secAdvPhy; /*!< Secondary Advertising PHY. */ - uint16_t advDID; /*!< Advertising Data ID. */ - uint8_t advSID; /*!< Advertising SID. */ - uint8_t scanReqNotifEna; /*!< Scan Request Notification Enable. */ + uint16_t advEventProp; /*!< Advertising Event Properties. */ + uint32_t priAdvInterMinUsec; /*!< Primary Advertising Interval Minimum in microseconds. */ + uint32_t priAdvInterMaxUsec; /*!< Primary Advertising Interval Maximum in microseconds. */ + uint32_t priAdvTermCntDownUsec; /*!< Primary Advertising termination count down in microseconds. */ + uint64_t peerAddr; /*!< Peer Address. */ + uint8_t priAdvChanMap; /*!< Primary Advertising Channel Map. */ + uint8_t ownAddrType; /*!< Own Address Type. */ + uint8_t peerAddrType; /*!< Peer Address Type. */ + uint8_t advFiltPolicy; /*!< Advertising Filter Policy. */ + int8_t advTxPwr; /*!< Advertising Tx Power. */ + uint8_t priAdvPhy; /*!< Primary Advertising PHY. */ + uint8_t secAdvMaxSkip; /*!< Secondary Advertising Maximum Skip. */ + uint8_t secAdvPhy; /*!< Secondary Advertising PHY. */ + uint16_t advDID; /*!< Advertising Data ID. */ + uint8_t advSID; /*!< Advertising SID. */ + uint8_t scanReqNotifEna; /*!< Scan Request Notification Enable. */ } lctrExtAdvParam_t; /*! \brief Periodic advertising parameters. */ @@ -129,10 +136,10 @@ typedef struct uint8_t perChHopInc; /*!< Periodic channel hop increment value. */ uint8_t perChIdx; /*!< Periodic LL Channel. */ bool_t shutdown; /*!< Client initiated shutdown flag. */ - uint32_t perAdvInter; /*!< Periodic advertising interval in BB ticks. */ + uint32_t perAdvInterUsec; /*!< Periodic advertising interval in microseconds. */ - uint32_t advInterMin; /*!< Periodic Advertising Interval Minimum in BB ticks. */ - uint32_t advInterMax; /*!< Periodic Advertising Interval Maximum in BB ticks. */ + uint32_t advInterMinUsec; /*!< Periodic Advertising Interval Minimum in microseconds. */ + uint32_t advInterMaxUsec; /*!< Periodic Advertising Interval Maximum in BB ticks. */ uint16_t advEventProp; /*!< Periodic Advertising Event Properties. */ bool_t advParamReady; /*!< Periodic Advertising Parameter is ready or not. */ @@ -190,8 +197,8 @@ typedef struct uint32_t auxDelayUsec; /*!< Auxiliary advertising event delay. */ uint8_t advDataFragLen; /*!< Advertising data fragmentation length. */ - /* Acad control block */ - lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< Acad parameters. */ + /* ACAD control block */ + lctrAcadParam_t acadParams[LCTR_ACAD_NUM_ID]; /*!< ACAD parameters. */ /* Periodic advertising parameters */ lctrPerAdvParam_t perParam; /*!< Periodic advertising parameters. */ @@ -206,7 +213,7 @@ typedef struct uint8_t extHdrFlags; /*!< Extended header flags. */ uint8_t *pExtAdvAuxPtr; /*!< Extended advertising PDU buffer location of AuxPtr field. */ uint8_t auxChHopInc; /*!< Auxiliary channel hop increment value. */ - uint32_t auxSkipInter; /*!< Total skip time in BB ticks. */ + uint32_t auxSkipInterUsec; /*!< Total skip time in microseconds. */ /* Buffers */ uint8_t advHdrBuf[LCTR_EXT_ADVB_LEN(LL_EXT_ADV_HDR_MAX_LEN, 0)]; @@ -225,7 +232,7 @@ typedef struct /* Connection context. */ bool_t isAuxConnReq; /*!< True if AUX_CONN_REQ is received, False if CONN_IND is received. */ - uint32_t connIndEndTs; /*!< Connection indication end timestamp. */ + uint32_t connIndEndTsUsec; /*!< Connection indication end timestamp in microseconds. */ bool_t connIndRcvd; /*!< Connection request received flag. */ uint8_t usedChSel; /*!< Used channel selection. */ @@ -242,6 +249,11 @@ typedef struct bool_t didPerUpdate; /*!< Data ID update due to periodic enable or disable. */ bool_t advBodAbort; /*!< TRUE if extended advertising BOD is aborted. */ lctrAdvbPduHdr_t rspPduHdr; /*!< Response PDU header. */ + + /* BIG */ + lctrAcadBigHdlr_t bigCreated; /*!< Function pointer to the BIG created action function. */ + lctrAcadBigHdlr_t bigTerminated; /*!< Function pointer to the BIG terminated action function. */ + lctrRemoveHdlr_t removeCback; /*!< Function pointer to the AdvSet remove action function. */ } lctrAdvSet_t; /*! \brief Slave extended advertising state context. */ @@ -258,6 +270,7 @@ extern lctrAdvSet_t *pLctrAdvSetTbl; extern LctrExtAdvMsg_t *pLctrSlvExtAdvMsg; extern lctrSlvExtAdvCtx_t lctrSlvExtAdv; extern LctrPerAdvMsg_t *pLctrSlvPerAdvMsg; +extern lctrAcadSlvMsg_t *pLctrAcadSlvMsg; /************************************************************************************************** Function Declarations @@ -284,17 +297,18 @@ void lctrSelectNextAuxChannel(lctrAdvSet_t *pAdvSet); void lctrSelectNextPerChannel(lctrAdvSet_t *pAdvSet); /* ISR: Packet handlers */ -void lctrSlvTxSetupExtAdvHandler(BbOpDesc_t *pOp, uint32_t txTime); +void lctrSlvTxSetupExtAdvHandler(BbOpDesc_t *pOp, uint32_t txTime); uint32_t lctrSlvTxSetupAuxAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd); uint32_t lctrSlvTxSetupAuxScanRspDataHandler(BbOpDesc_t *pOp, bool_t isChainInd); bool_t lctrSlvRxAuxScanReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); -void lctrSlvRxAuxScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); -void lctrSlvRxLegacyScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); +void lctrSlvRxAuxScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); +void lctrSlvRxLegacyScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); bool_t lctrSlvRxLegacyReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); -void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); +void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf); uint32_t lctrSlvTxSetupPeriodicAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd); -void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet); +void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet); +void lctrSlvAcadDisable(lctrAcadParam_t *pAcadParam); /* ISR: BOD handlers */ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp); @@ -324,6 +338,8 @@ void lctrPeriodicAdvActResetTerm(lctrAdvSet_t *pAdvSet); void lctrPeriodicAdvActAdvTerm(lctrAdvSet_t *pAdvSet); void lctrSlvAcadActChanMapUpdateStart(lctrAdvSet_t *pAdvSet); void lctrSlvAcadActChanMapUpdateFinish(lctrAdvSet_t *pAdvSet); +void lctrSlvAcadActBigCreated(lctrAdvSet_t *pAdvSet); +void lctrSlvAcadActBigTerminated(lctrAdvSet_t *pAdvSet); /* Reservation */ uint32_t lctrGetPerRefTime(uint8_t perHandle, uint32_t *pDurUsec); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis.h new file mode 100644 index 00000000000..c2541366d6c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis.h @@ -0,0 +1,292 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller connected isochronous interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_BIS_H +#define LCTR_INT_BIS_H + +#include "lctr_int_adv_slave_ae.h" +#include "lctr_int_adv_master_ae.h" +#include "lctr_int.h" +#include "lctr_int_iso.h" +#include "lctr_pdu_iso.h" +#include "bb_ble_api.h" +#include "pal_codec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Get encryption ID from BIG context. */ +#define LCTR_BIG_CTRL_ENC_ID(pBigCtx) (LL_MAX_CONN + LL_MAX_CIG + LL_MAX_BIG + (pBigCtx - &pLctrBigTbl[0])) + +/*! \brief ISO Data PDU start offset in a buffer. */ +#define LCTR_ISO_SDU_START_OFFSET (HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN - LL_ISO_DATA_HDR_LEN) + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +struct lctrBigCtx_tag; + +/*! \brief Broadcast Isochronous Stream (BIS) context. */ +typedef struct +{ + bool_t enabled; /*!< Enable flag. */ + uint8_t bisNum; /*!< BIS positional sequence number. */ + uint16_t handle; /*!< BIS handle. */ + struct lctrBigCtx_tag *pBigCtx; /*!< BIG context. */ + + union + { + struct + { + /* Data */ + wsfQueue_t txDataQ; /*!< Transmit ISO queue. */ + uint8_t numTxSduComp; /*!< Number of Tx completed SDUs. */ + lctrIsoalTxCtx_t isoalTxCtx; /*!< ISOAL transmit context. */ + } slv; /*!< BIS slave specific data. */ + + struct + { + /* Data */ + wsfQueue_t rxDataQ; /*!< Receive ISO Data PDU pending queue. */ + wsfQueue_t rxIsoSduQ; /*!< Receive ISO SDU PDU pending queue. */ + lctrIsoalRxCtx_t isoalRxCtx; /*!< ISOAL Receive context. */ + + /* ISO test */ + LlIsoTestCtrs_t stats; /*!< Rx statistics. */ + } mst; /*!< BIS master specific data. */ + } roleData; /*!< Role specific data. */ + + /* ISO test */ + struct + { + bool_t enabled; /*!< TRUE ISO test enabled, FALSE otherwise. */ + bool_t term; /*!< Flag for ISO test termination. */ + bool_t pendInit; /*!< Receive pending init. */ + union + { + struct + { + uint32_t payloadCtr; /*!< Payload counter for framed transmissions. */ + } framed; /*!< Framed context. */ + struct + { + uint8_t payloadOffset; /*!< Payload offset for unframed transmissions. */ + } unframed; /*!< Unframed context. */ + } util; /*!< Role-based utility variables. */ + LlIsoPldType_t pldType:8; /*!< Test payload type. */ + } test; /*!< ISO Test data. */ + + /* BB */ + lmgrChanParam_t chSelInfo; /*!< Channel selection state. */ + PalBbBleChan_t chan; /*!< Channelization parameters. */ + + /* Data */ + LlIsoDataPath_t path:8; /*!< Input audio data path. */ + LlIsoLlid_t lastLlid:8; /*!< Last LLID. */ +} lctrBisCtx_t; + +/*! \brief Broadcast Isochronous Group (BIG) context. */ +typedef struct lctrBigCtx_tag +{ + bool_t enabled; /*!< Context enabled. */ + uint8_t state; /*!< Current state. */ + uint8_t handle; /*!< BIG handle. */ + LlRole_t role:8; /*!< Role. */ + + /* Data */ + uint16_t maxPdu; /*!< Maximum size of BIS Data PDU. */ + uint16_t maxSdu; /*!< Maximum size of ISO SDU. */ + + /* Host */ + uint32_t sduInterUsec; /*!< SDU interval in microseconds. */ + uint32_t bisSpaceUsec; /*!< BIS space in microseconds. */ + uint32_t isoInterUsec; /*!< Isochronous PDU interval in microseconds. */ + uint8_t bn; /*!< Burst number. */ + uint8_t nse; /*!< Maximum number of subevent in each interval on BIS. */ + uint8_t pto; /*!< Pre-transmission offset. */ + uint8_t irc; /*!< Immediate repetition count. */ + LlFraming_t framing:8; /*!< BIS Data PDU format. */ + LlPacking_t packing:8; /*!< Packing sequence scheme. */ + + /* ISO Event */ + uint64_t eventCounter; /*!< Event counter. */ + uint32_t syncDelayUsec; /*!< Synchronization delay in microseconds. */ + uint32_t transLatUsec; /*!< The maximum transmission latency, in microseconds. */ + uint32_t subInterUsec; /*!< Subevent interval in microseconds. */ + + /* BIS */ + uint8_t numBis; /*!< Number of BISs. */ + lctrBisCtx_t *pBisCtx[LL_MAX_BIS]; /*!< BIS contexts. */ + + union + { + struct + { + lctrAdvSet_t *pAdvSet; /*!< Advertising Set parent. */ + wsfQueue_t txCtrlQ; /*!< Transmit BIG control queue. */ + bool_t notifyHostEst; /*!< Notify host event sent flag. */ + } slv; /*!< BIG slave specific data. */ + + struct + { + /* BIG Create Sync */ + lctrPerScanCtx_t *pPerScanCtx; /*!< Periodic Scan parent. */ + bool_t syncLostReason; /*!< BIG synchronization lost. */ + uint8_t mse; /*!< Maximum number of subevents. */ + uint8_t numBisIdx; /*!< Total number of BISes in the BIG. */ + uint8_t bisIdx[LL_MAX_BIS]; /*!< List of indices of BISes. */ + + /* Sync timeout */ + uint32_t bigSyncTimeoutMs; /*!< Synchronization timeout in microseconds. */ + wsfTimer_t bigSyncTmr; /*!< Synchronization timeout timer. */ + + /* Event state */ + uint16_t totalAcc; /*!< Total clock accuracy. */ + uint16_t extraWwUsec; /*!< Extra window widening time in microseconds. */ + uint32_t rxSyncTime; /*!< Last received BIG anchor point. */ + uint32_t anchorPoint; /*!< BIG anchor point. */ + + /* Encryption */ + uint8_t bcstCode[LL_BC_LEN]; /*!< Broadcast Code. */ + } mst; /*!< BIG master specific data. */ + } roleData; /*!< Role-specific data. */ + + /* Control */ + struct + { + uint8_t actMsk; /*!< Active control procedure bitmask. */ + uint8_t pendMsk; /*!< Pending control procedure bitmask. */ + uint8_t cssn; /*!< Control Subevent Sequence Number */ + struct + { + uint16_t inst; /*!< Instant. */ + uint64_t chanMap; /*!< Channel map. */ + } chanMapUpd; /*!< Channel Map Update data. */ + struct + { + uint16_t inst; /*!< Instant. */ + uint8_t reason; /*!< Termination reason. */ + } term; /*!< Terminate data. */ + } bcp; /*!< BIG Control Procedure data. */ + + /* BB */ + PalBbPhy_t phy:8; /*!< PHY used for the BIG. */ + BbOpDesc_t bod; /*!< BIG BOD. */ + BbBleData_t bleData; /*!< BLE BB operation data. */ + uint32_t seedAccAddr; /*!< Seed access address. */ + uint16_t baseCrcInit; /*!< Base CRC Init. */ + lmgrChanParam_t ctrChSelInfo; /*!< Control channel selection state. */ + PalBbBleChan_t ctrChan; /*!< BIG Control channelization parameters. */ + + /* Encryption */ + /* Note: located at end of structure for non-encryption optimization */ + bool_t encrypt; /*!< Encryption enable for BIS. */ + uint8_t giv[LL_GIV_LEN]; /*!< GIV. */ + uint8_t gskd[LL_GSKD_LEN]; /*!< GSKD. */ + + /* Reception status. */ + bool_t lastPduMissed; /*!< Rx failure on last PDU. */ +} lctrBigCtx_t; + +/*! \brief ISR subevent context. */ +typedef struct +{ + uint8_t bisEvtIdx; /*!< BIS event index within an event. */ + uint8_t burstIdx; /*!< Burst index within a subevent. */ + uint8_t repIdx; /*!< Repeat index within a subevent. */ + uint8_t ptIdx; /*!< Pre-transmission index within a subevent. */ +} lctrSeCtx_t; + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +extern lctrBisCtx_t *pLctrBisTbl; +extern lctrBigCtx_t *pLctrBigTbl; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* BIG Context */ +lctrBigCtx_t *lctrAllocBigCtx(uint8_t bigHandle); +void lctrFreeBigCtx(lctrBigCtx_t *pBigCtx); +uint8_t lctrBigIsPerAdvUsed(uint8_t handle); +lctrBigCtx_t *lctrFindBigByHandle(uint8_t bigHandle); +lctrBigCtx_t *lctrFindBigBySyncHandle(uint16_t syncHandle); +bool_t lctrIsBigSynchronizing(void); + +/* BIS Context */ +lctrBisCtx_t *lctrAllocBisCtx(lctrBigCtx_t *pBigCtx); +void lctrCleanupBisCtx(lctrBisCtx_t *pBisCtx); +void lctrFreeBisCtx(lctrBisCtx_t *pBisCtx); +lctrBisCtx_t *lctrFindBisByHandle(uint16_t bisHandle); +uint8_t lctrGetNumAvailBisCtx(void); +uint32_t lctrComputeBisAccessAddr(uint32_t seedAccAddr, uint8_t bisNum); +void lctrSetupBisContext(lctrBisCtx_t *pBisCtx, uint32_t seedAccAddr, uint16_t baseCrcInit, uint64_t chMap, LlPhy_t phy); +void lctrSelectBigChannels(lctrBigCtx_t *pBigCtx); +void lctrRemapBigChannels(lctrBigCtx_t *pBigCtx, uint64_t chanMap); + +/* BIS Tx Data Path */ +void lctrBisTxIsoPduQueue(lctrBisCtx_t *pBisCtx, lctrIsoHdr_t *pIsoHdr, uint8_t *pIsoSdu); +uint8_t lctrBisTxQueuePeek(lctrBisCtx_t *pBisCtx, uint8_t burstIdx, PalBbBleTxBufDesc_t *descs); +void lctrBisTxQueuePopCleanup(lctrBisCtx_t *pBisCtx, uint8_t numFrag); +uint8_t *lctrBigTxCtrlAlloc(uint8_t pduLen); +void lctrBigTxCtrlQueue(lctrBigCtx_t *pBigCtx, uint8_t *pBuf, uint8_t numReTx); +uint8_t *lctrBigTxCtrlQueuePeek(lctrBigCtx_t *pBigCtx); +void lctrBigTxCtrlQueuePop(lctrBigCtx_t *pBigCtx); +void lctrBigTxCtrlQueuePopCleanup(lctrBigCtx_t *pBigCtx); + +/* BIS Rx Data Path */ +uint8_t *lctrBisRxIsoSduDeq(lctrBisCtx_t *pBisCtx); +void lctrBisRxIsoSduEnq(lctrBisCtx_t *pBisCtx, uint8_t *pBuf); +uint8_t *lctrBisRxIsoDataPduAlloc(void); +void lctrBisRxIsoDataPduFree(uint8_t *pPdu); +void lctrBisEnqueueRxDataPdu(lctrBisCtx_t *pBisCtx, uint8_t *pRxBuf, uint64_t evtCtr); +uint8_t *lctrBisDequeueRxDataPdu(lctrBisCtx_t *pBisCtx, uint8_t *pEvtCtrLsb); + +/* ISO Test mode */ +uint8_t lctrBisTxTest(lctrBisCtx_t *pBisCtx, uint8_t pldType); +uint8_t lctrBisRxTest(lctrBisCtx_t *pBisCtx, uint8_t pldType); +uint8_t LctrBisReadTestCounters(lctrBisCtx_t *pBisCtx, LlIsoTestCtrs_t *pStats); + +/* BIS helper functions */ +void lctrBisDefaults(void); +void lctrNotifyIsoTxComplete(lctrBigCtx_t *pBigCtx); +void lctrBisCalcGroupSessionKey(const uint8_t *pGSKD, const uint8_t *pBC, uint8_t *pGSK); +uint8_t lctrBisSetDataPath(lctrBisCtx_t *pBisCtx, LlIsoDataPathDir_t dpDir, LlIsoDataPath_t dpId); +bool_t lctrSlvBisCalcNextIdxSequential(lctrBigCtx_t *pBigCtx, lctrSeCtx_t *pSeCtx, uint8_t numSePkts); +bool_t lctrSlvBisCalcNextIdxInterleaved(lctrBigCtx_t *pBigCtx, lctrSeCtx_t *pSeCtx, uint8_t numSePkts); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_BIS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_master.h new file mode 100644 index 00000000000..54b72e3adbd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_master.h @@ -0,0 +1,99 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller isochronous master interface file. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_BIS_MASTER_H +#define LCTR_INT_BIS_MASTER_H + +#include "lctr_api_bis_master.h" +#include "lctr_int_bis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Get reservation manager handle for BIG from the context pointer. */ +#define LCTR_GET_BIG_RM_HANDLE(pBigCtx) (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_BIG + (pBigCtx - &pLctrBigTbl[0])) + +/*! \brief Resolve BIG context pointer from the reservation manager handle. */ +#define LCTR_GET_BIG_RM_CTX(rmHandle) &(pLctrBigTbl[rmHandle - (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_BIG)]) + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Slave BIG broadcasting states. */ +typedef enum +{ + LCTR_MST_BIG_STATE_DISABLED, /*!< BIG master disabled state. */ + LCTR_MST_BIG_STATE_SYNCING, /*!< BIG master synchronizing state. */ + LCTR_MST_BIG_STATE_SYNCED, /*!< BIG master synchronized state. */ + LCTR_MST_BIG_STATE_SHUTDOWN, /*!< BIG master shutdown in progress. */ + LCTR_MST_BIG_STATE_RESET, /*!< BIG master reset in progress. */ + LCTR_MST_BIG_STATE_TOTAL /*!< Total number of BIG master states. */ +} lctrMstBigState_t; + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +extern lctrMstBigMsg_t *pLctrMstBigMsg; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Host Events */ +void lctrNotifyHostBigTerminateComplete(LlStatus_t status, uint8_t bigHandle); +void lctrNotifyHostSyncLost(uint8_t bigHandle, LlStatus_t reason); + +/* State machine for BIG master */ +void lctrMstBigSendMsg(lctrBigCtx_t *pBigCtx, LctrMstBigMsg_t event); +void lctrMstBigExecuteSm(lctrBigCtx_t *pBigCtx, LctrMstBigMsg_t event); + +/* Action routines */ +void lctrMstBigActStart(lctrBigCtx_t *pBigCtx); +void lctrMstBigActBigSync(lctrBigCtx_t *pBigCtx); +void lctrMstBigActTerm(lctrBigCtx_t *pBigCtx); +void lctrMstBigActShutdown(lctrBigCtx_t *pBigCtx); +void lctrMstBigActSyncLost(lctrBigCtx_t *pBigCtx); +void lctrMstBigActMicFailed(lctrBigCtx_t *pBigCtx); +void lctrMstBigActCleanup(lctrBigCtx_t *pBigCtx); + +/* Builder */ +void lctrMstBigBuildOp(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo); +void lctrMstSetupBigContext(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo); +void lctrMstSetupBigChannel(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo); + +/* ISR: BOD handlers */ +void lctrMstBisRxCompletion(BbOpDesc_t *pBod, uint8_t *pBuf, uint8_t status); +void lctrMstBigBeginOp(BbOpDesc_t *pOp); +void lctrMstBigEndOp(BbOpDesc_t *pOp); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_BIS_MASTER_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_slave.h new file mode 100644 index 00000000000..d5824f4dc2c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_bis_slave.h @@ -0,0 +1,95 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller isochronous slave interface file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_BIS_SLAVE_H +#define LCTR_INT_BIS_SLAVE_H + +#include "lctr_api_bis_slave.h" +#include "lctr_int_bis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Get reservation manager handle from BIG context. */ +#define LCTR_BIG_TO_RM_HANDLE(pBigCtx) (LL_MAX_CONN + LL_MAX_ADV_SETS + LL_MAX_CIG + (pBigCtx - &pLctrBigTbl[0])) + +/*! \brief Get BIG context from reservation manager handle. */ +#define LCTR_RM_HANDLE_TO_BIG(rmHandle) (&pLctrBigTbl[(rmHandle) - LL_MAX_CONN - LL_MAX_ADV_SETS - LL_MAX_CIG]) + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Slave BIS broadcasting states. */ +enum +{ + LCTR_SLV_BIG_STATE_DISABLED, /*!< BIS slave broadcasting disabled state. */ + LCTR_SLV_BIG_STATE_ENABLED, /*!< BIS slave broadcasting enabled state. */ + LCTR_SLV_BIG_STATE_SHUTDOWN, /*!< BIS slave broadcasting shutdown in progress. */ + LCTR_SLV_BIG_STATE_RESET, /*!< BIS slave broadcasting reset in progress. */ + LCTR_SLV_BIG_STATE_TOTAL /*!< Total number of extended advertising states. */ +}; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Host events */ +void lctrNotifyHostCreateBigComplete(lctrBigCtx_t *pBigCtx, uint8_t status); +void lctrNotifyHostTerminateBigComplete(lctrBigCtx_t *pBigCtx); + +/* State machine for BIS slave */ +void lctrSlvBigSendMsg(lctrBigCtx_t *pBigCtx, uint8_t event); +void lctrSlvBigSendAcadMsg(lctrBigCtx_t *pBigCtx, uint8_t event); +void lctrSlvBigExecuteSm(lctrBigCtx_t *pBigCtx, uint8_t event); + +/* Action routines */ +void lctrSlvBigActStart(lctrBigCtx_t *pBigCtx); +void lctrSlvBigActSendChMapUpd(lctrBigCtx_t *pBigCtx); +void lctrSlvBigActSendTerm(lctrBigCtx_t *pBigCtx); +void lctrSlvBigActShutdown(lctrBigCtx_t *pBigCtx); +void lctrSlvBigActCleanup(lctrBigCtx_t *pBigCtx); + +/* Builder */ +uint8_t lctrSlvBigBuildOp(lctrBigCtx_t *pBigCtx); + +/* ISR: Packet handlers */ +void lctrSlvBisTxCompletionSequential(BbOpDesc_t *pOp, uint8_t status); +void lctrSlvBisTxCompletionInterleaved(BbOpDesc_t *pOp, uint8_t status); + +/* ISR: BOD handlers */ +void lctrSlvBigBeginOp(BbOpDesc_t *pOp); +void lctrSlvBigEndOp(BbOpDesc_t *pOp); +void lctrSlvBigAbortOp(BbOpDesc_t *pOp); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_BIS_SLAVE_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis.h new file mode 100644 index 00000000000..02d678254f4 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis.h @@ -0,0 +1,535 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller connected isochronous stream interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_CIS_H +#define LCTR_INT_CIS_H + +#include "lmgr_api_iso.h" +#include "lctr_int.h" +#include "lctr_int_iso.h" +#include "lctr_int_conn.h" +#include "lctr_api_cis.h" +#include "lctr_pdu_conn.h" +#include "bb_ble_api.h" +#include "bb_ble_api_op.h" +#include "lctr_pdu_iso.h" +#include "wsf_timer.h" +#include "pal_codec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Maximum number of burst number. */ +#define LCTR_MAX_BN 0x0F + +/*! \brief Get reservation manager handle for CIG from the context pointer. */ +#define LCTR_GET_CIG_RM_HANDLE(pCigCtx) (LL_MAX_CONN + LL_MAX_ADV_SETS + (pCigCtx - &pLctrCigTbl[0])) + +/*! \brief Get topology manager handle for CIG from the context pointer. */ +#define LCTR_GET_CIG_TM_HANDLE(pCigCtx) (LL_MAX_CONN + LL_MAX_PER_SCAN + (pCigCtx - &pLctrCigTbl[0])) + +/*! \brief Resolve CIG context pointer from the reservation manager handle. */ +#define LCTR_GET_CIG_RM_CTX(rmHandle) &(pLctrCigTbl[rmHandle - (LL_MAX_CONN + LL_MAX_ADV_SETS)]) + +/*! \brief Resolve CIG context pointer from the topology manager handle. */ +#define LCTR_GET_CIG_TM_CTX(rmHandle) &(pLctrCigTbl[rmHandle - (LL_MAX_CONN + LL_MAX_PER_SCAN)]) + +/*! \brief ISO Data PDU start offset in a buffer. */ +#define LCTR_CIS_DATA_PDU_START_OFFSET 3 + +/*! \brief Data PDU start offset in a buffer. */ +#define LCTR_CIS_DATA_TX_PDU_START_OFFSET 0 + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief CIS main states. */ +enum +{ + LCTR_CIS_STATE_IDLE, /*!< CIS idle state. */ + LCTR_CIS_STATE_EST, /*!< CIS established state. */ + LCTR_CIS_STATE_SHUTDOWN, /*!< CIS terminating state. */ + LCTR_CIS_STATE_TOTAL /*!< Total number of CIS slave states. */ +}; + +/*! \brief CIS termination states. */ +enum +{ + LCTR_CIS_TERM_STATE_IDLE, /*!< Idle state. */ + LCTR_CIS_TERM_STATE_TERMINATING, /*!< Wait for LL_CIS_RSP state. */ + LCTR_CIS_TERM_STATE_TOTAL /*!< Total CIS states. */ +}; + +/*! \brief CIS termination procedure events. */ +enum +{ + LCTR_CIS_TERM_EVENT_HOST_DISC, /*!< Received host disconnect CIS. */ + LCTR_CIS_TERM_EVENT_PEER_DISC, /*!< Received peer disconnect CIS. */ + LCTR_CIS_TERM_EVENT_INT_START_DISC, /*!< Start pending host disconnect CIS procedure. */ + LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC, /*!< Start pending peer disconnect CIS procedure. */ + LCTR_CIS_TERM_EVENT_CIS_TERM, /*!< Received CIS terminated event. */ + LCTR_CIS_TERM_EVENT_TOTAL, /*!< Total CIS events. */ + LCTR_CIS_TERM_EVENT_INVALID = 0xFF /*!< Invalid event. */ +}; + +/*! \brief CIS PDU type. */ +enum +{ + LCTR_CIS_PDU_DEFAULT, /*!< Default PDU. */ + LCTR_CIS_PDU_NULL, /*!< NULL PDU. */ + LCTR_CIS_PDU_EMPTY, /*!< Empty PDU. */ + LCTR_CIS_PDU_NON_EMPTY /*!< Non-empty PDU. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Parameters related to Tx flush timeout. */ +typedef struct +{ + bool_t pduAcked; /*!< TRUE if current PDU is acked, for Tx only. */ + bool_t pduRcved; /*!< TRUE if current PDU is received, for Rx only. */ + uint8_t bn; /*!< Burst number for the flush timeout. */ + uint8_t pduCounter; /*!< Current PDU counter in term of BN. */ + uint8_t subEvtCounter; /*!< Current subevent counter before flush timeout. */ + uint8_t intervalTotal; /*!< Total number interval before flush timeout. */ + uint8_t intervalCounter; /*!< Current interval counter. */ + + uint8_t lastSubEvtFt[LCTR_MAX_BN]; /*!< Last subevent the PDU could be transmitted before flush timeout for each PDU(in the last interval). */ + uint8_t pduType[LCTR_MAX_BN]; /*!< PDU type, whether NULL, empty or non-empty. */ + bool_t isPduDone[LCTR_MAX_BN]; /*!< TRUE if the PDU is either acked or flushed. */ +} lctrFtParam_t; + +/*! \brief Flush timeout parameter node. */ +typedef struct ftNode +{ + lctrFtParam_t ftParam; /*!< Flush time parameter. */ + struct ftNode *pNext; /*!< Pointer to the next node. */ +} lctrFtParamNode_t; + +/*! \brief Flush timeout parameter list. */ +typedef struct ftList +{ + lctrFtParamNode_t *pHead; /*!< Pointer to the head of the CIS linked list. */ + lctrFtParamNode_t *pTail; /*!< Pointer to the tail of the CIS linked list. */ + uint8_t numNodes; /*!< Number of nodes in the CIS linked list. */ +} lctrFtParamList_t; + +/*! \brief Connected isochronous stream context. */ +typedef struct +{ + bool_t enabled; /*!< Enable flag. */ + uint8_t state; /*!< main state. */ + uint8_t estState; /*!< Establishment procedure state. */ + uint8_t termState; /*!< Termination procedure state. */ + uint16_t aclHandle; /*!< ACL handle. */ + uint16_t cisHandle; /*!< CIS handle. */ + uint8_t role; /*!< Role. */ + uint8_t cigId; /*!< Used to identify the connected isochronous group. */ + uint8_t cisId; /*!< Used to identify a connected isochronous stream. */ + uint16_t cisEvtCounter; /*!< Event counter. */ + uint32_t cisSyncDelayUsec; /*!< CIS synchronous delay in microsecond. */ + uint32_t cigSyncDelayUsec; /*!< CIG synchronous delay in microsecond. */ + bool_t cisDone; /*!< CIS transfer is done, no more subevent for the CIS. Used for interleaved CIS only. */ + bool_t isClosing; /*!< TRUE if the context is closing. */ + + uint8_t subEvtCounter; /*!< Sub event counter. */ + bool_t isTxDone; /*!< TRUE if all the Tx are done, start sending NULL packet. */ + bool_t pduFlushed; /*!< TRUE if the PDU is flushed, for Tx only. */ + + uint8_t reason; /*!< Disconnect reason. */ + lctrCisTermInd_t cisTerm; /*!< Peer CIS Disconnect reason. */ + + uint64_t txPktCounter; /*!< Transmit packet counter. */ + uint64_t rxPktCounter; /*!< Receive packet counter. */ + + /* Buffers */ + uint8_t dataHdrBuf[LL_DATA_HDR_LEN]; /*!< Data header buffer */ + uint8_t dataBuf[10]; /*!< Data header buffer */ + uint16_t dataCounter; /*!< Data counter. */ + + /* LLCP */ + bool_t isCisReqPend; /*!< True if CIS_REQ is sent and response is not received yet. */ + uint16_t ceRef; /*!< ACL connection event where the offset referenced. */ + uint16_t cisCeRef; /*!< Number of CIS event before CIS is started. */ + uint32_t offsetUsec; /*!< Time in microsecond between the start of the referenced CE to the start of first CIS event. */ + wsfTimer_t tmrProcRsp; /*!< Procedure response timer. */ + + union + { + struct + { + uint32_t anchorOffsetUsec; /*!< Offset to the stream anchor point. */ + lctrCisReq_t cisReq; /*!< CIS request parameters. */ + bool_t syncWithMaster; /*!< Flag indicating synchronize packet received from master. */ + bool_t rxFromMaster; /*!< At least one successful packet received from master. */ + bool_t firstRxFromMaster; /*!< TRUE if the first Rx from master. */ + uint32_t offsetUsec; /*!< Offset to the next Rx. */ + uint32_t firstRxStartTsUsec; /*!< Timestamp of the first received frame regardless of CRC error in microseconds. */ + uint8_t consCrcFailed; /*!< Number of consecutive CRC failures. */ + uint8_t rxStatus; /*!< Rx status. */ + } slv; /*!< Slave connection specific data. */ + + struct + { + bool_t txPduIsAcked; /*!< TRUE if the PDU is acked. */ + bool_t rxFromSlave; /*!< At least one packet received from slave. */ + } mst; /*!< CIS master specific data. */ + } data; /*!< role-specific data. */ + + /* Channel parameters */ + lmgrChanParam_t chanParam; /*!< Channel parameter. */ + uint8_t chIdx; /*!< LL channel index. */ + uint8_t nextSubEvtChanIdx; /*!< Next subevent channel index. */ + uint32_t accessAddr; /*!< Access address. */ + uint32_t crcInit; /*!< CRC initialization value. */ + + /* Flow control */ + lctrCisDataPduHdr_t txHdr; /*!< Transmit data PDU header. */ + lctrCisDataPduHdr_t rxHdr; /*!< Receive data PDU header. */ + wsfQueue_t txIsoQ; /*!< Transmit ISO queue. */ + wsfQueue_t txArqQ; /*!< Transmit ARQ queue. */ + uint8_t numTxComp; /*!< Number of completed Tx buffers. */ + uint32_t delayUsec; /*!< Time between the start of subevent to the start of next subevent in microsecond. + Same as subEvtInter for sequential scheme, different for interleaved scheme. */ + uint8_t *pRxBuf; /*!< Pointer to the RX buffer later to be cleaned. */ + bool_t validRx; /*!< TRUE if the RX buffer is valid and shall be processed. */ + bool_t txPduIsAcked; /*!< TRUE if the TX PDU is acked. */ + bool_t txBufPendAck; /*!< A transmit buffer is pending acknowledgement. */ + + /* Flush timeout Tx/Rx list */ + lctrFtParamList_t txFtParamList; /*!< Tx flush timeout parameters list. */ + lctrFtParamList_t rxFtParamList; /*!< Rx flush timeout parameters list. */ + + /* Data length */ + lctrDataLen_t localDataPdu; /*!< Local Data PDU parameters. */ + + /* BB data */ + BbBleData_t bleData; /*!< BLE BB operation data. */ + + /* Supervision */ + uint16_t supTimeoutMs; /*!< Supervision timeout in milliseconds. */ + wsfTimer_t tmrSupTimeout; /*!< Supervision timer. */ + bool_t connEst; /*!< Connection established. */ + bool_t powerIndReq; /*!< Power control indication required when established conn. */ + + /* Encryption */ + uint8_t iv[LL_IV_LEN]; /*!< Initialization vector. */ + + /* PHY */ + uint8_t phyMToS; /*!< Master to slave PHY. */ + uint8_t phySToM; /*!< Slave to master PHY. */ + + /* Data */ + uint8_t sca; /*!< Sleep clock accuracy. */ + uint8_t packing; /*!< Packing scheme. */ + uint8_t framing; /*!< Indicates the format of CIS Data PDUs. */ + uint16_t sduSizeMToS; /*!< Maximum SDU size from the master Host. */ + uint16_t sduSizeSToM; /*!< Maximum SDU size from the slave Host. */ + uint32_t sduIntervalMToS; /*!< Time interval between the start of consecutive SDUs from the master Host in microseconds */ + uint32_t sduIntervalSToM; /*!< Time interval between the start of consecutive SDUs from the master Host in microseconds */ + uint16_t isoInterval; /*!< Isochronous PDU interval in 1.25ms unit. */ + uint8_t ftMToS; /*!< Master to slave flush time. */ + uint8_t ftSToM; /*!< Slave to master flush time. */ + uint8_t nse; /*!< Maximum number of subevent in each interval on CIS. */ + uint32_t subIntervUsec; /*!< Subevent duration in microsecond. */ + uint8_t bnMToS; /*!< Master to slave burst number. */ + uint8_t bnSToM; /*!< Slave to master burst number. */ + uint32_t transLatUsec; /*!< The maximum time, in microseconds, for transmission of SDUs of all CISes. */ + uint32_t nextCisOffsetUsec; /*!< For slave sequential packing only, from the start of this CIS to the start of the next CIS. */ + + /* BB/ISR context */ + bool_t firstFromPeer; /*!< TRUE if received once from peer, used for fast supervision timeout. */ + uint8_t txDataCounter; /*!< Tx data counter in each ISO interval, used to determine whether continue operation for the BOD or not. */ + uint8_t rxDataCounter; /*!< Rx data counter in each ISO interval, used to determine whether continue operation for the BOD or not. */ + + /* Datapath configuration */ + lctrInDataPathCtx_t dataPathInCtx; /*!< Input data path config. */ + lctrOutDataPathCtx_t dataPathOutCtx; /*!< Output data path context. */ + + /* ISO test */ + bool_t txTestEnabled; /*!< TRUE ISO test enabled, FALSE otherwise. */ + bool_t rxTestEnabled; /*!< TRUE if ISO RX test enabled, FALSE otherwise. */ + uint32_t testSduTs; /*!< Timestamp of last tx sdu. */ + LlIsoPldType_t testPldType:8; /*!< Test payload type. */ + + uint32_t expectedPkt; /*!< Next expected packet for Rx test. */ + uint32_t testTxPktCtr; /*!< Packet counter for TX test. */ + uint32_t numRxSuccess; /*!< ISO Rx received payload counter. */ + uint32_t numRxMissed; /*!< ISO Rx missed payload counter. */ + uint32_t numRxFailed; /*!< ISO Rx failed payload counter. */ + uint8_t isoRxPldType; /*!< ISO RX payload length type. */ + bool_t rxPendInit; /*!< ISO test pending initialization flag. */ + + LlIsoLinkQual_t isoLinkQualStats; /*!< ISO Link quality statistics. */ + + lctrIsoalTxCtx_t isoalTxCtx; /*!< ISOAL transmit context. */ + lctrIsoalRxCtx_t isoalRxCtx; /*!< Partial receive context. */ +} lctrCisCtx_t; + +/*! \brief Connected isochronous stream node. */ +typedef struct node +{ + lctrCisCtx_t *pCisCtx; /*!< CIS context. */ + struct node *pNext; /*!< Next node. */ +} lctrCisNode_t; + +/*! \brief Connected isochronous stream linked list. */ +typedef struct list +{ + lctrCisNode_t *pHead; /*!< Pointer to the head of the CIS linked list. */ + lctrCisNode_t *pTail; /*!< Pointer to the tail of the CIS linked list. */ + uint8_t numNodes; /*!< Number of nodes in the CIS linked list. */ +} lctrCisList_t; + +/*! \brief Connected isochronous group context. */ +typedef struct +{ + bool_t enabled; /*!< Context enabled. */ + uint8_t packing; /*!< Packing scheme. */ + bool_t isBodBuilt; /*!< TRUE if BOD is built. */ + bool_t isBodStarted; /*!< TRUE if BOD is started. */ + bool_t isRmAdded; /*!< TRUE if reservation is added. */ + uint8_t cigId; /*!< Used to identify the connected isochronous group. */ + uint16_t cigHandle; /*!< CIG handle. */ + uint32_t cigSyncDelayUsec; /*!< CIG synchronous delay in microsecond. */ + uint16_t isoInterval; /*!< Isochronous PDU interval in 1.25ms unit. */ + bool_t isValid; /*!< TRUE if CIS parameters are valid and is able to be scheduled. */ + uint8_t numCisEsted; /*!< Number of CISs that are established. */ + bool_t isLoopBack; /*!< TRUE if all the CIS streams have been traversed once. */ + bool_t headCisRmved; /*!< TRUE if the head CIS in the CIG is removed. */ + uint32_t offsetUsec; /*!< Only valid when headCisRmved is TRUE, duration between the old anchor point and new anchor point. */ + uint32_t firstRxStartTsUsec; /*!< Only valid when headCisRmved is TRUE, timestamp of the first received frame regardless of CRC error. */ + + /* BB data */ + BbOpDesc_t cigBod; /*!< CIG BOD. */ + + /* Linked list of CIS context. */ + lctrCisCtx_t *pCisCtx; /*!< Pointer to the current CIS context. */ + lctrCisList_t list; /*!< CIS linked list. */ + + /* BOD data. */ + union + { + struct + { + uint16_t cigEvtCounter; /*!< Event counter. */ + uint32_t anchorPointUsec; /*!< Anchor point in microseconds. */ + uint16_t lastActiveEvent; /*!< Last active event counter. */ + uint16_t totalAcc; /*!< Combined sleep clock inaccuracy. */ + } slv; /*!< Slave BOD data. */ + + struct + { + uint8_t numCis; /*!< Number of CIS. */ + } mst; /*!< Master BOD data. */ + } roleData; /*!< Role-specific BOD Data. */ + + PalBbBleTxBufDesc_t dataPdu[3]; /*!< Data PDU descriptor. */ +} lctrCigCtx_t; + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +extern lctrCisCtx_t *pLctrCisTbl; +extern lctrCigCtx_t *pLctrCigTbl; +extern lctrCisMsg_t *pLctrCisMsg; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +/* State machine */ +void lctrCisExecuteSm(lctrCisCtx_t *pCisCtx, uint8_t event); +bool_t lctrLlcpExecuteCisTermSm(lctrConnCtx_t *pCtx, uint8_t event); +void lctrCisDisp(lctrCisMsg_t *pMsg); + +/* Action routines for main state machine */ +void lctrCisActCisEst(lctrCisCtx_t *pCtx); +void lctrCisActCisEstFail(lctrCisCtx_t *pCtx); +void lctrCisActDisc(lctrCisCtx_t *pCtx); +void lctrCisActClosed(lctrCisCtx_t *pCisCtx); +void lctrCisActFail(lctrCisCtx_t *pCisCtx); + +/* Action routines for LLCP termination state machine */ +void lctrCisLlcpActHostDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisLlcpActPeerDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisLlcpActCisTerm(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisLlcpActIntHostDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisLlcpActIntPeerDisc(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/* CIS Context */ +lctrCisCtx_t *lctrAllocCisCtx(lctrCigCtx_t *pCigCtx); +void lctrCleanupCtx(lctrCisCtx_t *pCisCtx); +void lctrFreeCisCtx(lctrCisCtx_t *pCisCtx); +lctrCisCtx_t *lctrFindCisByHandle(uint16_t cisHandle); +lctrCisCtx_t *lctrFindCisById(uint8_t cigId, uint8_t cisId); +uint8_t lctrGetNumAvailCisCtx(); +uint8_t lctrGetNumEnabledCisCtx(LlCisCigParams_t *pSetCigParam); +uint8_t lctrGetNumEnabledCisCtxTest(LlCisCigParamsTest_t *pSetCigParam); +uint8_t lctrGetNumEstCisCtx(LlCisCigParams_t *pSetCigParam); +uint8_t lctrGetNumEstCisCtxTest(LlCisCigParamsTest_t *pSetCigParam); +uint8_t lctrGetNumEstCisCtxByCigCtx(lctrCigCtx_t *pCigCtx); + +/* CIS list utility functions */ +bool_t lctrCisInsertHead(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx); +bool_t lctrCisInsertTail(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx); +bool_t lctrCisRemoveHead(lctrCisList_t *pList); +bool_t lctrCisRemoveTail(lctrCisList_t *pList); +bool_t lctrCisRemoveMiddle(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx); +bool_t lctrCisRemove(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx); +bool_t lctrCisIsListEmpty(lctrCisList_t *pList); +uint8_t lctrCisGetListCount(lctrCisList_t *pList); +lctrCisCtx_t * lctrCisGetHeadCis(lctrCisList_t *pList); +bool_t lctrCisIsHeadCis(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx); +lctrCisCtx_t * lctrCisGetNextCis(lctrCisList_t *pList, lctrCisCtx_t *pCurCis); +lctrCisCtx_t * lctrCisGetPreCis(lctrCisList_t *pList, lctrCisCtx_t *pCurCis); +bool_t lctrCisAreCisCtxDone(lctrCisList_t *pList); +void lctrCisClearCisDone(lctrCisList_t *pList); +void lctrCisSetCisDone(lctrCisList_t *pList, lctrCisCtx_t *pCurCisCtx); + +/* CIS flush timeout list utility functions */ +lctrFtParamNode_t * lctrCisFtCreateFtParamNode(lctrFtParam_t *pFtParam); +bool_t lctrCisFtInsertHead(lctrFtParamList_t *pList, lctrFtParam_t *pFtParam); +bool_t lctrCisFtInsertTail(lctrFtParamList_t *pList, lctrFtParam_t *pFtParam); +bool_t lctrCisFtRemoveHead(lctrFtParamList_t *pList); +bool_t lctrCisFtRemoveTail(lctrFtParamList_t *pList); +bool_t lctrCisFtIsListEmpty(lctrFtParamList_t *pList); +void lctrCisFtListClear(lctrFtParamList_t *pList); + +/* CIG Context */ +lctrCigCtx_t *lctrAllocCigCtx(uint8_t cigId); +void lctrFreeCigCtx(lctrCigCtx_t *pCigCtx); +lctrCigCtx_t *lctrFindCigById(uint8_t cigId); +uint8_t lctrGetNumAvailCigCtx(); + +/* Helper */ +void lctrCisDefaults(void); +bool_t lctrIsCisEst(lctrCisCtx_t *pCtx); +void lctrCisSetupChanParam(lctrCisCtx_t *pCisCtx, uint64_t chanMask); +void lctrCisSetupEncrypt(lctrCisCtx_t *pCisCtx); +void lctrCisStoreTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreDisconnectReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreConnFailEstablishTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreLlcpTimeoutTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreLocalLowResourceTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreMicFailedTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreConnTimeoutTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStoreLlcpPeerRejTerminateReason(lctrCisCtx_t *pCisCtx); +void lctrCisStartLlcpTimer(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisStopLlcpTimer(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrCisInitFtParam(lctrFtParam_t *pTxFtParam, uint8_t bn, uint8_t ft, uint8_t nse); +uint32_t lctrCisCalcSubEvtDurationUsecSeq(uint8_t phyMToS, uint8_t phySToM, uint8_t plMToS, uint8_t plSToM); +uint32_t lctrCisCalcSubEvtDurationUsecInter(LlCisCigParams_t *pSetCigParam); +void LctrCisUpdateChanMap(uint16_t aclHandle); +void lctrCleanupCigCtx(); + +/* Function used by connection context */ +bool_t lctrCheckForCisLinkTerm(uint16_t aclHandle); +bool_t lctrCheckIsCisEstAcl(uint16_t aclHandle); +bool_t lctrCheckIsCisEstCis(uint16_t cisHandle); + +/* CIS Tx data path */ +uint16_t lctrIsoTxInitMem(uint8_t *pFreeMem, uint32_t freeMemSize); +void lctrCisTxDataPduQueue(lctrCisCtx_t *pCtx, lctrIsoHdr_t *pIsoHdr, uint8_t *pIsoBuf); +uint8_t lctrCisTxQueuePeek(lctrCisCtx_t *pCisCtx, PalBbBleTxBufDesc_t *bbDescs); +bool_t lctrCisTxQueuePop(lctrCisCtx_t *pCisCtx); +void lctrCisTxQueuePopCleanup(lctrCisCtx_t *pCisCtx); +uint8_t lctrCisTxQueueClear(lctrCisCtx_t *pCisCtx); + +/* CIS Rx data path */ +uint8_t *lctrCisRxPduAlloc(uint16_t maxRxLen); +void lctrCisRxPduFree(uint8_t *pBuf); +void lctrCisRxEnq(uint8_t *pBuf, uint16_t eventCounter, uint16_t cisHandle); +uint8_t *lctrCisRxDeq(uint16_t *pConnHandle); + +/* Message */ +void lctrSendCisMsg(lctrCisCtx_t *pCisCtx, uint8_t event); +void lctrSendCisLlcpMsg(lctrCisCtx_t *pCisCtx, uint8_t event); + +/* Notification */ +void lctrNotifyHostCisEst(lctrCisCtx_t *pCisCtx, uint8_t status, uint32_t cigSyncDelayUsec); +void lctrNotifyHostCisTerm(lctrCisCtx_t *pCisCtx); + +/* ISR */ +uint16_t lctrCisSetupForTx(lctrCigCtx_t *pCigCtx, uint8_t rxStatus, bool_t reqTx); +bool_t lctrCisProcessRxAck(lctrCisCtx_t *pCisCtx); +bool_t lctrCisProcessTxAck(lctrCisCtx_t *pCisCtx); +void lctrCisTxPduAck(lctrCisCtx_t *pCisCtx); +void lctrCisProcessTxAckCleanup(lctrCisCtx_t *pCisCtx); +void lctrCisRxPostProcessing(lctrCisCtx_t *pCisCtx, uint8_t *pRxBuf); +void lctrCisTxTestPayloadHandler(lctrCisCtx_t * pCisCtx); +void lctrCisPowerMonitorCheckRssi(int8_t rssi, uint8_t status, uint8_t phy, lctrConnCtx_t *pConnCtx); + +/* Scheduler */ +BbOpDesc_t *lctrCisResolveConflict(BbOpDesc_t *pNewOp, BbOpDesc_t *pExistOp); + +/*************************************************************************************************/ +/*! + * \brief Increment the Tx/encrypt packet counter. + * + * \param pCisCtx Connection context. + */ +/*************************************************************************************************/ +static inline void lctrCisIncPacketCounterTx(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->txPktCounter++; + + /* Set the new packet counter for inline encryption. */ + if (lctrSetEncryptPktCountHdlr) + { + lctrSetEncryptPktCountHdlr(&pCisCtx->bleData.chan.enc, pCisCtx->txPktCounter); + } +} + +/*************************************************************************************************/ +/*! + * \brief Increment the Rx/decrypt packet counter. + * + * \param pCisCtx Connection context. + */ +/*************************************************************************************************/ +static inline void lctrCisIncPacketCounterRx(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->rxPktCounter++; + + /* Set the new packet counter for inline encryption. */ + if (lctrSetDecryptPktCountHdlr) + { + /* lctrSetDecryptPktCountHdlr(&pCisCtx->bleData.chan.enc, pCisCtx->rxPktCounter); */ /* Not necessary. */ + } +} + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_CIS_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_master.h new file mode 100644 index 00000000000..92263d06ea5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_master.h @@ -0,0 +1,115 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller master connected isochronous stream interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_CIS_MASTER_H +#define LCTR_INT_CIS_MASTER_H + +#include "lctr_int.h" +#include "lctr_int_conn.h" +#include "lctr_int_cis.h" +#include "lctr_api_cis_master.h" +#include "lmgr_api_cis_master.h" +#include "bb_ble_api.h" +#include "bb_ble_api_op.h" +#include "wsf_timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief CIS master establishment states. */ +enum +{ + LCTR_CIS_MST_EST_STATE_IDLE, /*!< Idle state. */ + LCTR_CIS_MST_EST_STATE_CIS_RSP, /*!< Wait for LL_CIS_RSP state. */ + LCTR_CIS_MST_EST_STATE_TOTAL /*!< Total CIS master establishment states. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Create CIS pending. */ +typedef struct +{ + uint8_t numCis; /*!< Number of CISs to create. */ + uint16_t cisHandle[LL_MAX_CIS]; /*!< CIS handle array. */ + uint16_t aclHandle[LL_MAX_CIS]; /*!< ACL handle array. */ + uint8_t isCreateCisDone[LL_MAX_CIS]; /*!< TRUE if create CIS is done, either succeed or fail. */ +} lctrCreateCisPend_t; + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +/* State machine for CIS LLCP */ +bool_t lctrMstLlcpExecuteCisEstSm(lctrConnCtx_t *pCtx, uint8_t event); + +/* Builder */ +void lctrMstCisBuildCigOp(lctrCigCtx_t *pCigCtx); +void lctrMstCisCigOpCommit(lctrCigCtx_t *pCigCtx, lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrMstCisBuildCisData(lctrCisCtx_t *pCisCtx); + +/* ISR: Packet handlers */ +void lctrMstCisCigTxCompletion(BbOpDesc_t *pOp, uint8_t status); +void lctrMstCisCigRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status); + +/* ISR: BOD handlers */ +uint32_t lctrMstCisCheckContOp(BbOpDesc_t *pOp, bool_t *pNewCisCtx); +void lctrMstCisCigBeginOp(BbOpDesc_t *pOp); +void lctrMstCisCigContOp(BbOpDesc_t *pOp); +void lctrMstCisCigPostSubEvt(BbOpDesc_t *pOp, uint8_t status); +void lctrMstCisCigEndOp(BbOpDesc_t *pOp); +void lctrMstCisCigCleanupOp(BbOpDesc_t *pOp); +void lctrMstCisCigAbortOp(BbOpDesc_t *pOp); + +/* Action routines for CIS master LLCP state machine */ +void lctrMstCisLlcpActHostCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrMstCisLlcpActPeerRej(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrMstCisLlcpActPeerCisRsp(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrMstCisLlcpActRspTimeout(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrMstCisLlcpActLocalReject(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/* Reservation */ +uint32_t lctrGetCigRefTime(uint8_t connHandle, uint32_t *pDurUsec); + +/* Utility function */ +void lctrMstCreateCisDone(lctrCisCtx_t *pCisCtx); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_CIS_MASTER_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_slave.h new file mode 100644 index 00000000000..344c528ff2d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_cis_slave.h @@ -0,0 +1,107 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller connected isochronous stream slave interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_CIS_SLAVE_H +#define LCTR_INT_CIS_SLAVE_H + +#include "lctr_int.h" +#include "lctr_api_cis.h" +#include "lctr_int_conn.h" +#include "lctr_int_cis.h" +#include "lctr_api_cis_slave.h" +#include "lmgr_api_cis_slave.h" +#include "bb_ble_api.h" +#include "bb_ble_api_op.h" +#include "wsf_timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/************************************************************************************************** + Constants +**************************************************************************************************/ +/*! \brief CIS slave establishment states. */ +enum +{ + LCTR_CIS_SLV_EST_STATE_IDLE, /*!< Idle state. */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /*!< Wait for host reply state. */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /*!< Wait for LL_CIS_IND state. */ + LCTR_CIS_SLV_EST_STATE_TOTAL /*!< Total CIS slave establishment states. */ +}; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +/* State machine for CIS LLCP */ +bool_t lctrSlvLlcpExecuteCisEstSm(lctrConnCtx_t *pCtx, uint8_t event); + +/* Builder */ +void lctrSlvCisBuildCigOp(lctrCigCtx_t *pCigCtx); +void lctrSlvCisCigOpCommit(lctrCigCtx_t *pCigCtx, lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisBuildCisData(lctrCisCtx_t *pCisCtx); + +/* ISR: Packet handlers */ +void lctrSlvCisCigTxCompletion(BbOpDesc_t *pOp, uint8_t status); +void lctrSlvCisCigRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status); + +/* ISR: BOD handlers */ +void lctrSlvCisCigBeginOp(BbOpDesc_t *pOp); +void lctrSlvCisCigContOp(BbOpDesc_t *pOp); +void lctrSlvCisCigPostSubEvt(BbOpDesc_t *pOp, uint8_t status); +uint32_t lctrSlvCisCheckContOp(BbOpDesc_t *pOp, bool_t *pNewCisCtx); +void lctrSlvCisCigEndOp(BbOpDesc_t *pOp); +void lctrSlvCisCigCleanupOp(BbOpDesc_t *pOp); +void lctrSlvCisCigAbortOp(BbOpDesc_t *pOp); + +/* Action routines for CIS slave LLCP state machine */ +void lctrSlvCisLlcpActPeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisLlcpActRejCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisLlcpActAcpCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisLlcpActPeerCisInd(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisLlcpActPeerCisRej(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); +void lctrSlvCisLlcpActIntPeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/* Reservation */ + +/* Helper */ +void lctrCisStorePeerCisReq(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_CIS_SLAVE_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn.h index 12b61aee478..dce8cd882ea 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Internal link layer controller connection interface file. + * \file + * + * \brief Internal link layer controller connection interface file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -47,9 +48,7 @@ extern "C" { #define LCTR_MAX_CONS_CRC 2 /*!< Maximum number of consecutive CRC failures. */ -#ifndef LCTR_DATA_PDU_START_OFFSET #define LCTR_DATA_PDU_START_OFFSET 2 /*!< Data PDU start offset in a buffer (match ACL header size). */ -#endif #define LCTR_DATA_PDU_FC_OFFSET 0 /*!< Flow control fields data PDU offset. */ #define LCTR_DATA_PDU_LEN_OFFSET 1 /*!< Length field data PDU offset. */ @@ -68,6 +67,28 @@ extern "C" { /*! \brief Resolve connection context from the handle. */ #define LCTR_GET_CONN_CTX(h) &(pLctrConnTbl[h]) +/*! \brief Resolve txPower from phy index. */ +#define LCTR_GET_TXPOWER(pCtx, phy, option) \ + (pCtx->phyTxPower[phy - (((phy == LL_PHY_LE_CODED) && (option == BB_PHY_OPTIONS_BLE_S2)) ? 0 : 1)]) + +/*! \brief Set the txpower of a specified PHY. */ +#define LCTR_SET_TXPOWER(pCtx, phy, pow) (pCtx->phyTxPower[phy - 1] = pow) + +/*! \brief Low threshold for power monitoring. */ +#define LCTR_RSSI_LOW_THRESHOLD -65 + +/*! \brief High threshold for power monitoring. */ +#define LCTR_RSSI_HIGH_THRESHOLD -30 + +/*! \brief Minimum time spent until request. */ +#define LCTR_PC_MIN_TIME 15 + +/*! \brief Default request of increase/decrease in value. */ +#define LCTR_PC_REQUEST_VAL 5 + +/*! \brief Special reset terminate reason. */ +#define LCTR_RESET_TERM_REASON 0xFF + /************************************************************************************************** Data Types **************************************************************************************************/ @@ -139,12 +160,31 @@ enum LCTR_PROC_CIS_EST_PEER, /*!< Peer-initiated CIS establishment procedure. */ LCTR_PROC_CIS_TERM, /*!< CIS termination procedure. */ LCTR_PROC_CIS_TERM_PEER, /*!< Peer-initiated CIS termination procedure. */ + LCTR_PROC_PWR_IND, /*!< Power indication prodecure. */ + LCTR_PROC_PWR_CTRL, /*!< Power control procedure. */ LCTR_PROC_INVALID = 0xFF /*!< Invalid ID. */ /* Note: additional procedures without instants can be overridden. */ }; +/*! \brief Power control monitor schemes. */ +enum +{ + LCTR_PC_MONITOR_AUTO, /*!< Automatic monitoring scheme. */ + LCTR_PC_MONITOR_PATH_LOSS, /*!< Path loss monitoring scheme. */ + + LCTR_PC_MONITOR_SCHEME_TOTAL /*!< Total number of monitoring schemes. */ +}; + +/*! \brief Power control scheme states. */ +enum +{ + LCTR_PC_MONITOR_DISABLED, /*!< Disabled monitoring. */ + LCTR_PC_MONITOR_ENABLED, /*!< Monitoring enabled. */ + LCTR_PC_MONITOR_READY /*!< Monitoring ready for enable. */ +}; + /*! \brief Check if CIS is enabled by the CIS handle signature. */ typedef bool_t (*lctrCheckCisEstCisFn_t)(uint16_t cisHandle); /*! \brief Check for CIS termination signature. */ @@ -175,7 +215,7 @@ typedef struct uint16_t totalAcc; /*!< Combined sleep clock inaccuracy. */ uint16_t lastActiveEvent; /*!< Last active event counter. */ uint32_t txWinSizeUsec; /*!< Tx window size. */ - uint32_t anchorPoint; /*!< Anchor point. */ + uint32_t anchorPointUsec; /*!< Anchor point in microseconds. */ uint32_t unsyncedTime; /*!< Unsynced time in BB tick before connection update. */ bool_t initAckRcvd; /*!< Ack received from master. */ bool_t abortSlvLatency; /*!< If TRUE abort slave latency. */ @@ -183,7 +223,7 @@ typedef struct uint8_t consCrcFailed; /*!< Number of consecutive CRC failures. */ bool_t syncWithMaster; /*!< Flag indicating synchronize packet received from master. */ bool_t rxFromMaster; /*!< At least one successful packet received from master. */ - uint32_t firstRxStartTs; /*!< Timestamp of the first received frame regardless of CRC error. */ + uint32_t firstRxStartTsUsec; /*!< Timestamp of the first received frame regardless of CRC error in microseconds. */ } slv; /*!< Slave connection specific data. */ @@ -200,6 +240,7 @@ typedef struct /* RF parameters */ int8_t rssi; /*!< RSSI. */ + uint8_t lastRxStatus; /*!< Status code of last rx. */ /* Channel parameters */ uint8_t lastChanIdx; /*!< Current channel index. */ @@ -212,6 +253,8 @@ typedef struct uint16_t chIdentifier; /*!< Channel identifier. */ uint32_t crcInit; /*!< CRC initialization value. */ uint32_t accessAddr; /*!< Connection access address. */ + int8_t phyTxPower[LL_PC_PHY_TOTAL]; + /*!< Saved txPower configuration for PHYs. */ /* Flow control */ lctrDataPduHdr_t txHdr; /*!< Transmit data PDU header. */ @@ -262,6 +305,11 @@ typedef struct uint64_t usedFeatSet; /*!< Used feature set. */ uint8_t peerSca; /*!< Peer SCA. */ + int8_t peerTxPower; /*!< Peer reported txPower. */ + uint8_t peerPwrLimits; /*!< Peer power limits field. */ + uint8_t peerApr[LL_PC_PHY_TOTAL]; + /*!< Acceptable reduction of power as calculated by the peer. */ + /* Data length */ lctrDataLen_t localDataPdu; /*!< Local Data PDU parameters. */ lctrDataLen_t effDataPdu; /*!< Effective Data PDU parameters. */ @@ -316,12 +364,49 @@ typedef struct lctrPhyUpdInd_t phyUpd; /*!< PHY update parameters. */ wsfTimer_t tmrProcRsp; /*!< Procedure response timer. */ uint8_t scaUpdAction; /*!< Sca update action variable. */ + bool_t readRemoteTxPower; /*!< Currently reading remote txPower. */ int8_t scaMod; /*!< Local sca override modifier. */ + uint8_t reqErrCode; /*!< LLCP error code. */ + + /* Power Control */ + int8_t delta; /*!< Power control delta storage. */ + bool_t peerReqRecvd; /*!< Peer request received. */ + uint8_t reqPhy; /*!< PHY of most recent power control request. */ + bool_t powerRptLocal; /*!< Currently reporting local power changes. */ + bool_t powerRptRemote; /*!< Currently reporting remote power changes. */ + uint8_t powerMonitorScheme; /*!< Active power monitoring scheme. */ + uint8_t monitoringState; /*!< Current state of active power monitoring scheme. */ + bool_t controllerInitRead; /*!< A controller initiated read command. */ + union + { + struct + { + int8_t highThreshold; /*!< High extreme RSSI threshold. */ + int8_t lowThreshold; /*!< Low extreme RSSI threshold. */ + uint8_t minTimeSpent; /*!< Minimum time spent in an extreme RSSI zone to trigger a request. */ + uint8_t curTimeSpent; /*!< Current time spent in an extreme RSSI zone. */ + uint8_t requestVal; /*!< Value of increase/decrease in power to request. */ + } autoMonitor; /*!< Autonomous RSSI monitoring specific data. */ + + struct + { + uint8_t highThreshold; /*!< Path loss high threshold. */ + uint8_t highHysteresis; /*!< Path loss high hysteresis. */ + uint8_t lowThreshold; /*!< Path loss low threshold. */ + uint8_t lowHysteresis; /*!< Path loss low hysteresis. */ + uint8_t minTimeSpent; /*!< Minimum time spent to trigger an event. */ + uint8_t curTimeSpent; /*!< Current time spent in a new path loss zone. */ + uint8_t curZone; /*!< Current path loss zone. */ + uint8_t newZone; /*!< New zone. */ + bool_t initialPathLossRead; /*!< A power control request is required to start path loss monitoring. */ + } pathLoss; /*!< Path loss parameters. */ + } pclMonitorParam; /*!< Power control monitoring data. */ /* CIS */ - uint16_t llcpCisHandle; /*!< CIS handle for the LLCP procedure. */ - lctrCheckTermFn_t checkCisTerm; /*!< Pointer to the check CIS termination function. */ - lctrCheckCisEstAclFn_t checkCisEstAcl;/*!< Pointer to the check if CIS is established function. */ + uint16_t llcpCisHandle; /*!< CIS handle for the LLCP procedure. */ + lctrCheckTermFn_t checkCisTerm; /*!< Pointer to the check CIS termination function. */ + lctrCheckCisEstAclFn_t checkCisEstAcl; /*!< Pointer to the check if CIS is established function. */ + uint8_t cisRssiExtremeTimeSpent; /*!< CIS's current time spent in an extreme zone. */ } lctrConnCtx_t; /*! \brief Call signature of a cipher block handler. */ @@ -348,6 +433,18 @@ typedef uint8_t (*LctrChSelHdlr_t)(lctrConnCtx_t *pCtx, uint16_t numSkip); /*! \brief Call signature of an action handler. */ typedef void (*lctrLlcpEh_t)(lctrConnCtx_t *pCtx); +/*! \brief Call signature of a power monitor function. */ +typedef void (*lctrPcMonAct_t)(lctrConnCtx_t *pCtx); + +/*! \brief Call signature of power change indication handler. */ +typedef void (*lctrPcPowInd_t)(lctrConnCtx_t *pCtx, uint8_t phy, int8_t delta, int8_t txPower, bool_t phyChange); + +/*! \brief Call signature of power report notification handler. */ +typedef void (*lctrPcNotifyPwr_t)(lctrConnCtx_t *pCtx, uint8_t reason, uint8_t phy, int8_t txPower, uint8_t limits, int8_t delta); + +/*! \brief Call signature of CIS pend disconnect function. */ +typedef bool_t (*lctrPendCisDisc_t)(lctrConnCtx_t *pCtx); + /*! \brief LLCP state machine handlers. */ enum { @@ -357,6 +454,7 @@ enum LCTR_LLCP_SM_PHY_UPD, /*!< PHY update state machine. */ LCTR_LLCP_SM_CIS_EST, /*!< CIS establishment state machine. */ LCTR_LLCP_SM_CIS_TERM, /*!< CIS termination state machine. */ + LCTR_LLCP_SM_PC, /*!< Power control state machine. */ LCTR_LLCP_SM_CMN, /*!< Common LLCP state machine. */ LCTR_LLCP_SM_TOTAL /*!< Total number of LLCP state machine. */ }; @@ -382,6 +480,9 @@ extern lctrLlcpEh_t lctrSendPerSyncFromBcstFn; extern lctrLlcpEh_t lctrStorePeriodicSyncTrsfFn; extern lctrLlcpEh_t lctrSendPeriodicSyncIndFn; extern lctrLlcpEh_t lctrReceivePeriodicSyncIndFn; +extern lctrPcMonAct_t lctrPcActTbl[LCTR_PC_MONITOR_SCHEME_TOTAL]; +extern lctrPcPowInd_t lctrSendPowerChangeIndCback; +extern lctrPcNotifyPwr_t lctrNotifyPowerReportIndCback; /************************************************************************************************** Function Declarations @@ -465,7 +566,7 @@ void lctrReceivePeriodicSyncInd(lctrConnCtx_t *pCtx); void lctrSendPerSyncFromScan(lctrConnCtx_t *pCtx); void lctrSendPerSyncFromBcst(lctrConnCtx_t *pCtx); -/* Request peer SCA actions */ +/* Request peer SCA actions. */ void lctrStoreScaAction(lctrConnCtx_t *pCtx); void lctrSendPeerScaReq(lctrConnCtx_t *pCtx); void lctrSendPeerScaRsp(lctrConnCtx_t *pCtx); @@ -530,6 +631,8 @@ bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDu uint32_t lctrCalcPingPeriodMs(lctrConnCtx_t *pCtx, uint32_t authTimeoutMs); uint8_t lctrComputeSca(void); uint32_t lctrConnGetAnchorPoint(lctrConnCtx_t *pCtx, uint16_t ceCounter); +void lctrInitPhyTxPower(lctrConnCtx_t *pCtx); +uint8_t lctrGetPowerLimits(int8_t txPower); /* Reservation */ uint32_t lctrGetConnRefTime(uint8_t connHandle, uint32_t *pDurUsec); @@ -539,8 +642,6 @@ uint32_t lctrGetConnRefTime(uint8_t connHandle, uint32_t *pDurUsec); * \brief Set flags for link termination. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrFlagLinkTerm(lctrConnCtx_t *pCtx) @@ -561,8 +662,6 @@ static inline void lctrFlagLinkTerm(lctrConnCtx_t *pCtx) * \brief Service the Control PDU ACK state after a successful reception. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrCheckControlPduAck(lctrConnCtx_t *pCtx) @@ -579,8 +678,6 @@ static inline void lctrCheckControlPduAck(lctrConnCtx_t *pCtx) * \brief Service the Control PDU ACK state after a successful transmission. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrSetControlPduAck(lctrConnCtx_t *pCtx) @@ -627,8 +724,6 @@ static inline bool_t lctrCheckForLinkTerm(lctrConnCtx_t *pCtx) * \brief Increment the Tx/encrypt packet counter. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrIncPacketCounterTx(lctrConnCtx_t *pCtx) @@ -650,8 +745,6 @@ static inline void lctrIncPacketCounterTx(lctrConnCtx_t *pCtx) * \brief Increment the Rx/decrypt packet counter. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrIncPacketCounterRx(lctrConnCtx_t *pCtx) @@ -673,8 +766,6 @@ static inline void lctrIncPacketCounterRx(lctrConnCtx_t *pCtx) * \brief Set the transmit packet counter value in the BB. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrSetBbPacketCounterTx(lctrConnCtx_t *pCtx) @@ -693,7 +784,7 @@ static inline void lctrSetBbPacketCounterTx(lctrConnCtx_t *pCtx) case PAL_BB_NONCE_MODE_PKT_CNTR: lctrSetEncryptPktCountHdlr(pEnc, pCtx->txPktCounter); break; - case PAL_BB_NONCE_MODE_EVT_CNTR: + case PAL_BB_NONCE_MODE_EXT16_CNTR: lctrSetEncryptPktCountHdlr(pEnc, pCtx->eventCounter); break; default: @@ -707,8 +798,6 @@ static inline void lctrSetBbPacketCounterTx(lctrConnCtx_t *pCtx) * \brief Set the receive packet counter value in the BB. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrSetBbPacketCounterRx(lctrConnCtx_t *pCtx) @@ -727,7 +816,7 @@ static inline void lctrSetBbPacketCounterRx(lctrConnCtx_t *pCtx) case PAL_BB_NONCE_MODE_PKT_CNTR: lctrSetDecryptPktCountHdlr(pEnc, pCtx->rxPktCounter); break; - case PAL_BB_NONCE_MODE_EVT_CNTR: + case PAL_BB_NONCE_MODE_EXT16_CNTR: lctrSetDecryptPktCountHdlr(pEnc, pCtx->eventCounter); break; default: @@ -764,8 +853,6 @@ static inline bool_t lctrCheckActiveOrPend(lctrConnCtx_t *pCtx, uint8_t proc) * \brief Store connection timeout termination reason. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrStoreConnTimeoutTerminateReason(lctrConnCtx_t *pCtx) @@ -779,8 +866,6 @@ static inline void lctrStoreConnTimeoutTerminateReason(lctrConnCtx_t *pCtx) /*************************************************************************************************/ /*! * \brief Increment available Tx data buffers. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrDataTxIncAvailBuf(void) @@ -795,8 +880,6 @@ static inline void lctrDataTxIncAvailBuf(void) /*************************************************************************************************/ /*! * \brief Decrement available Tx data buffers. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrDataTxDecAvailBuf(void) @@ -813,9 +896,7 @@ static inline void lctrDataTxDecAvailBuf(void) * \brief Increment available Rx data buffers. * * \param numBufs Number of completed packets. - * - * \return None. - */ + */ /*************************************************************************************************/ static inline void lctrDataRxIncAvailBuf(uint8_t numBufs) { @@ -843,52 +924,6 @@ static inline bool_t lctrGetConnOpFlag(lctrConnCtx_t *pCtx, uint32_t flag) return (pCtx->opModeFlags & flag) ? TRUE : FALSE; } -/*************************************************************************************************/ -/*! - * \brief Convert PHYS bit to PHY. - * - * \param physBit PHYS bit. - * - * \return PHY. - */ -/*************************************************************************************************/ -static inline uint8_t lctrPhysBitToPhy(uint8_t physBit) -{ - switch (physBit) - { - default: - case LL_PHYS_LE_1M_BIT: - return BB_PHY_BLE_1M; - case LL_PHYS_LE_2M_BIT: - return BB_PHY_BLE_2M; - case LL_PHYS_LE_CODED_BIT: - return BB_PHY_BLE_CODED; - } -} - -/*************************************************************************************************/ -/*! - * \brief Convert PHY to PHYS bit. - * - * \param phy PHY. - * - * \return PHYS bit. - */ -/*************************************************************************************************/ -static inline uint8_t lctrPhyToPhysBit(uint8_t phy) -{ - switch (phy) - { - default: - case BB_PHY_BLE_1M: - return LL_PHYS_LE_1M_BIT; - case BB_PHY_BLE_2M: - return LL_PHYS_LE_2M_BIT; - case BB_PHY_BLE_CODED: - return LL_PHYS_LE_CODED_BIT; - } -} - /*************************************************************************************************/ /*! * \brief Get LLCP procedure ID. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_master.h index 93516040214..9bd5fc26665 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller master connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller master connection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -75,7 +76,6 @@ void lctrMstSetEstablishConn(lctrConnCtx_t *pCtx); void lctrMstReloadDataPdu(lctrConnCtx_t *pCtx); /* Helper */ -uint32_t lctrMstConnAdjustOpStart(lctrConnCtx_t *pCtx, uint32_t scanRefTime, uint32_t scanMinDurUsec, lctrConnInd_t *pConnInd); #ifdef __cplusplus }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_slave.h index b130cc7d041..d971314c0fd 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_slave.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_conn_slave.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller slave connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller slave connection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_master.h index b79b9e5c4ef..5a11a37dc7e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller master connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller master connection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_slave.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_slave.h index 95f66d273f7..94c464fb199 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_slave.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_enc_slave.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller slave connection interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller slave connection interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master.h index c2756bbdeef..562b5323848 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller scanning master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master_ae.h index dc429b89be2..b01010a549f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_init_master_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller scanning master interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller scanning master interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -90,7 +91,6 @@ uint8_t lctrMstAuxInitiateBuildOp(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t *p void lctrMstExtInitiateOpCommit(lctrExtScanCtx_t *pExtInitCtx); /* ISR: Initiate packet handlers */ -void lctrMstExtPreInitiateExecHandler(BbOpDesc_t *pOp); bool_t lctrMstInitiateRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); void lctrMstInitiateRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); bool_t lctrMstInitiateRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_iso.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_iso.h new file mode 100644 index 00000000000..47ff93cb7c4 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_iso.h @@ -0,0 +1,263 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller connection interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_ISO_H +#define LCTR_INT_ISO_H + +#include "lctr_api_iso.h" +#include "lctr_int.h" +#include "lctr_int_conn.h" +#include "lctr_pdu_iso.h" +#include "lmgr_api_iso.h" +#include "ll_defs.h" +#include "wsf_cs.h" +#include "pal_codec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +#define LCTR_ISO_DATA_PDU_FC_OFFSET 0 /*!< Flow control fields data PDU offset. */ +#define LCTR_ISO_DATA_PDU_LEN_OFFSET 1 /*!< Length field CIS or BIS Data PDU offset. */ + +/*! \brief First CIS handle (follows ACL handles). */ +#define LCTR_FIRST_CIS_HANDLE (pLctrRtCfg->maxConn) + +/*! \brief First BIS handle (follows CIS handles). */ +#define LCTR_FIRST_BIS_HANDLE (pLctrRtCfg->maxConn + pLctrRtCfg->maxCis) + +/*! \brief Fragment header maximum length. */ +#define LCTR_ISO_FRAG_HDR_MAX_LEN (LL_ISO_DATA_HDR_LEN + LL_ISO_SEG_HDR_LEN + LL_ISO_SEG_TO_LEN) + +/*! \brief Fragment trailer maximum length. */ +#define LCTR_ISO_FRAG_TRL_MAX_LEN LL_DATA_MIC_LEN + +/*! \brief SDU offset to start of the SDU data buffer. */ +#define LCTR_ISO_SDU_DATA_START_OFFSET HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN + +/************************************************************************************************** + Type Definitions +**************************************************************************************************/ + +/*! \brief Transmit buffer descriptor. */ +typedef struct +{ + uint8_t *pIsoSdu; /*!< ISO buffer. */ + uint8_t *pPduBuf; /*!< PDU data buffer. */ + uint16_t isoLen; /*!< ISO SDU length. */ + uint8_t fragLen; /*!< Fragmentation length. */ + uint8_t fragCnt; /*!< Current fragmentation Tx count. */ + struct + { + uint8_t hdrLen; /*!< Data PDU header length. */ + uint8_t trlLen; /*!< Data PDU trailer length. */ + uint8_t hdr[LCTR_ISO_FRAG_HDR_MAX_LEN]; /*!< Data PDU header. */ + uint8_t trl[LCTR_ISO_FRAG_TRL_MAX_LEN]; /*!< Data PDU trailer (i.e., MIC). */ + } frag[]; /*!< Fragmented Data PDU packet data. */ +} lctrIsoTxBufDesc_t; + +/*! \brief Start stream call signature. */ +typedef bool_t (*lctrCodecStartStream)(uint16_t id, PalCodecSreamParam_t *pParam); + +/*! \brief Stop stream call signature. */ +typedef void (*lctrCodecStopStream)(uint16_t id); + +/*! \brief Stream in data call signature. */ +typedef uint16_t (*lctrCodecStreamIn)(uint16_t id, uint8_t *pBuf, uint16_t len, uint32_t *pPktCtr); + +/*! \brief Stream out data call signature. */ +typedef void (*lctrCodecStreamOut)(uint16_t id, const uint8_t *pBuf, uint16_t len, uint32_t pktCtr); + +/*! \brief Codec event handlers. */ +typedef struct +{ + lctrCodecStartStream start; /*!< Start stream. */ + lctrCodecStopStream stop; /*!< Stop stream. */ + lctrCodecStreamIn in; /*!< Stream data input. */ + lctrCodecStreamOut out; /*!< Stream data output. */ +} lctrCodecHandlers_t; + +/*! \brief Codec event handlers. */ +extern lctrCodecHandlers_t lctrCodecHdlr; + +/*! \brief Transmit ISOAL Context. */ +typedef struct +{ + wsfQueue_t pendingSduQ; /*!< ISO pending SDU queue. */ + uint8_t pendQueueSize; /*!< Pending queue size. */ + uint16_t sduOffset; /*!< Offset of incomplete SDU. */ + uint8_t compSdu; /*!< Number of completed SDUs for current ISO event. */ +} lctrIsoalTxCtx_t; + +/*! \brief Receive ISOAL Context. */ +typedef struct +{ + uint8_t *pPendSduBuf; /*!< Pointer to incomplete SDU buffer. */ + uint16_t rxSduOffset; /*!< Offset of SDU currently being assembled. */ + bool_t pduFlushed; /*!< Most recent PDU was flushed due to failed RXs. */ + uint8_t rxState; /*!< RX state. */ + uint16_t packetSequence; /*!< Packet sequence number. */ + + union + { + struct + { + uint32_t timeOffset; /*!< Time offset of an SDU. */ + } framed; /*!< Framed specific data. */ + + struct + { + wsfQueue_t pendSduQ; /*!< Pending PDU fragments. */ + uint16_t curLen; /*!< Current length of SDU being received. */ + uint8_t ps; /*!< Packet status. */ + } unframed; /*!< Unframed specific data. */ + } data; /*!< Framing-specific data. */ +} lctrIsoalRxCtx_t; + +/*! \brief Input datapath context. */ +typedef struct +{ + LlIsoDataPath_t id; /*!< Input data path ID. */ +} lctrInDataPathCtx_t; /*!< Input datapath configuration. */ + +/*! \brief Output datapath context. */ +typedef struct +{ + LlIsoDataPath_t id; /*!< Output data path ID. */ + + union + { + struct + { + wsfQueue_t rxDataQ; /*!< Receive data pending queue. */ + uint8_t numRxPend; /*!< Number of messages pending in the RX queue. */ + } hci; /*!< HCI data path configuration. */ + } cfg; /*!< Datapath-specific configuration parameters. */ +} lctrOutDataPathCtx_t; /*!< Output datapath configuration. */ + +/*! \brief Datapath context. */ +typedef union +{ + lctrInDataPathCtx_t in; /*!< Input context. */ + lctrOutDataPathCtx_t out; /*!< Output context. */ +} lctrDataPathCtx_t; /*!< Datapath context collection. */ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Task event handler */ +void lctrIsoTxCompletedHandler(void); +void lctrCisRxPendingHandler(void); +void lctrNotifyHostIsoEventComplete(uint8_t handle, uint32_t evtCtr); + +/* ISO data path */ +lctrIsoTxBufDesc_t *lctrAllocIsoTxBufDesc(void); +void lctrFreeIsoTxBufDesc(lctrIsoTxBufDesc_t *pDesc); +uint8_t lctrSetupIsoDataPath( LlIsoSetupDataPath_t *pSetupDataPath, lctrDataPathCtx_t *pDataPathCtx); +void lctrIsoSendCodecSdu(uint16_t id); +bool_t lctrIsoRxConnEnq(lctrOutDataPathCtx_t *pOutDataPathCtx, uint16_t handle, uint8_t *pBuf); +void lctrIsoOutDataPathClear(lctrOutDataPathCtx_t *pOutCtx); +void lctrIsoalRxDataPathClear(lctrIsoalRxCtx_t *pRxCtx, uint8_t framing); +void lctrIsoOutDataPathSetup(lctrOutDataPathCtx_t *pOutCtx); +uint8_t *lctrIsoRxConnDeq(lctrOutDataPathCtx_t *pOutCtx); +bool_t lctrIsoUnframedRxSduPendQueue(lctrIsoalRxCtx_t *pRxCtx, uint8_t *pSdu, uint16_t handle, + uint16_t dataLen, uint8_t llid); + +/* ISO Test mode. */ +uint8_t *lctrGenerateIsoTestData(uint16_t handle, LlIsoPldType_t pldType, uint16_t maxSdu, uint32_t pktCtr); +void lctrValidateIsoTestData(uint8_t *pPld, uint8_t actLen, LlIsoTestCtrs_t *pRxStats, uint8_t pldType, uint16_t expMaxSdu, uint32_t expPldCtr); +/* ISOAL Utility. */ +uint8_t lctrAssembleTxFramedPdu(lctrIsoalTxCtx_t *pIsoalTxCtx, uint8_t *pPduBuf, uint16_t maxPduLen); +uint8_t lctrAssembleRxFramedSdu(lctrIsoalRxCtx_t *pIsoalRxCtx, wsfQueue_t *pRxQueue, + uint16_t handle, uint8_t *pIsoBuf, uint8_t len); +uint8_t *lctrTxIsoDataPduAlloc(void); + +/*************************************************************************************************/ +/*! + * \brief Increment available Tx data buffers. + */ +/*************************************************************************************************/ +static inline void lctrIsoSduTxIncAvailBuf(void) +{ + WSF_CS_INIT(); + + WSF_CS_ENTER(); + lmgrIsoCb.availTxBuf++; + WSF_CS_EXIT(); +} + +/*************************************************************************************************/ +/*! + * \brief Decrement available Tx data buffers. + */ +/*************************************************************************************************/ +static inline void lctrIsoSduTxDecAvailBuf(void) +{ + WSF_CS_INIT(); + + WSF_CS_ENTER(); + lmgrIsoCb.availTxBuf--; + WSF_CS_EXIT(); +} + +/*************************************************************************************************/ +/*! + * \brief Increment available Rx data buffers. + * + * \param numBufs Number of additional buffers available. + */ +/*************************************************************************************************/ +static inline void lctrIsoDataRxIncAvailBuf(uint8_t numBufs) +{ + WSF_CS_INIT(); + + WSF_CS_ENTER(); + lmgrIsoCb.availRxBuf += numBufs; + WSF_CS_EXIT(); +} + +/*************************************************************************************************/ +/*! + * \brief Decrement available Rx data buffers. + */ +/*************************************************************************************************/ +static inline void lctrIsoDataRxDecAvailBuf(void) +{ + WSF_CS_INIT(); + + WSF_CS_ENTER(); + lmgrIsoCb.availRxBuf--; + WSF_CS_EXIT(); +} + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_ISO_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_master_phy.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_master_phy.h index 7436d860cb9..21520b9336a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_master_phy.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_master_phy.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller PHY features (master) interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller PHY features (master) interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_pc.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_pc.h new file mode 100644 index 00000000000..8127ddc50b6 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_pc.h @@ -0,0 +1,76 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Internal link layer controller power control interface file. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_INT_PC_H +#define LCTR_INT_PC_H + +#include "lctr_api.h" +#include "lctr_int_conn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + External Constants +**************************************************************************************************/ + +/*! \brief Master LLCP state machine table. */ +extern LctrLlcpHdlr_t lctrMstLlcpSmTbl[LCTR_LLCP_SM_TOTAL]; + +/*! \brief Slave LLCP state machine table. */ +extern LctrLlcpHdlr_t lctrSlvLlcpSmTbl[LCTR_LLCP_SM_TOTAL]; + +/************************************************************************************************* + * Function Declarations +*************************************************************************************************/ +uint8_t lctrCalcPathLossZone(lctrConnCtx_t *pCtx); +void lctrNotifyHostPathLossRpt(lctrConnCtx_t *pCtx); +void lctrPathLossMonitorAct(lctrConnCtx_t *pCtx); + +/* Power indication actions. */ +void lctrStorePeerPowerInd(lctrConnCtx_t *pCtx); +void lctrSendPeerPowerRsp(lctrConnCtx_t *pCtx); + +/* Power control actions. */ +void lctrStorePowerControlAction(lctrConnCtx_t *pCtx); +void lctrSendPeerPowerControlReq(lctrConnCtx_t *pCtx); +void lctrStorePeerPowerControlReq(lctrConnCtx_t *pCtx); +void lctrSendPeerPowerControlRsp(lctrConnCtx_t *pCtx); +void lctrStorePeerPowerControlRsp(lctrConnCtx_t *pCtx); + +/* Power monitoring actions. */ +void lctrAutoPowerMonitorAct(lctrConnCtx_t *pCtx); + +/* Power reporting actions. */ +void lctrNotifyPowerReportInd(lctrConnCtx_t *pCtx, uint8_t reason, uint8_t phy, int8_t txPower, uint8_t limits, int8_t delta); +int8_t lctrAttemptTxPowerChange(lctrConnCtx_t *pCtx, uint8_t phy, int8_t delta); +void lctrSendPowerChangeInd(lctrConnCtx_t *pCtx, uint8_t phy, int8_t delta, int8_t txPower, bool_t phyChange); + +/* State machine */ +bool_t lctrLlcpExecutePclSm(lctrConnCtx_t *pCtx, uint8_t event); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_INT_PC_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_priv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_priv.h index 488a72fde1e..d948eabeeec 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_priv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_priv.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller privacy interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller privacy interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_slave_phy.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_slave_phy.h index 12762e9fe63..73a86c037ce 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_slave_phy.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_int_slave_phy.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal link layer controller PHY features (slave) interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal link layer controller PHY features (slave) interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master.c index 21f48e7dfe8..be3b7a73b05 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master advertising event ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master advertising event ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,8 +45,6 @@ extern bool_t bbTxAccAddrShiftMask; * \brief End a discovery scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstDiscoverEndOp(BbOpDesc_t *pOp) @@ -102,18 +101,18 @@ void lctrMstDiscoverEndOp(BbOpDesc_t *pOp) /*** Reschedule operation ***/ /* Reset due time to start of scan window. */ - pOp->due = pCtx->scanWinStart; + pOp->dueUsec = pCtx->scanWinStartUsec; if ((pCtx->scanParam.scanInterval != pCtx->scanParam.scanWindow) && ((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pCtx->scanParam.scanWindow))) { - const uint32_t min = BB_US_TO_BB_TICKS(pScan->elapsedUsec); - const uint32_t max = BB_BLE_TO_BB_TICKS(pCtx->scanParam.scanWindow); + const uint32_t min = pScan->elapsedUsec; + const uint32_t max = BB_BLE_TO_US(pCtx->scanParam.scanWindow); if (SchInsertEarlyAsPossible(pOp, min, max)) { /* Continue interrupted operation. */ - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pCtx->scanWinStart); + pScan->elapsedUsec = BbGetTargetTimeDelta(pOp->dueUsec, pCtx->scanWinStartUsec); WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); return; } @@ -128,33 +127,33 @@ void lctrMstDiscoverEndOp(BbOpDesc_t *pOp) if (pCtx->scanParam.scanInterval == pCtx->scanParam.scanWindow) { - /* Continuous scan. */ + /* Continuous scan, move to the next scan window. */ SchInsertNextAvailable(pOp); - pCtx->scanWinStart = pOp->due; + pCtx->scanWinStartUsec = pOp->dueUsec; } else { /* Next scan interval. */ - const uint32_t min = BB_BLE_TO_BB_TICKS(pCtx->scanParam.scanInterval); - const uint32_t max = min + BB_BLE_TO_BB_TICKS(pCtx->scanParam.scanWindow); + const uint32_t min = BB_BLE_TO_US(pCtx->scanParam.scanInterval); + const uint32_t max = min + BB_BLE_TO_US(pCtx->scanParam.scanWindow); while (TRUE) { /* Store start of next scan window. */ - pCtx->scanWinStart = pOp->due + min; + pCtx->scanWinStartUsec = pOp->dueUsec + min; if (SchInsertEarlyAsPossible(pOp, min, max)) { - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pCtx->scanWinStart); + pScan->elapsedUsec = BbGetTargetTimeDelta(pOp->dueUsec, pCtx->scanWinStartUsec); WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); break; } else { /* Advance to next scan window. */ - pOp->due = pCtx->scanWinStart; + pOp->dueUsec = pCtx->scanWinStartUsec; - LL_TRACE_WARN1("!!! Scan schedule conflict at due=%u", pOp->due + min); + LL_TRACE_WARN1("!!! Scan schedule conflict at dueUsec=%u", pOp->dueUsec + min); LL_TRACE_WARN1("!!! scanWindowUsec=%u", LCTR_BLE_TO_US(pCtx->scanParam.scanWindow)); } } @@ -259,8 +258,6 @@ bool_t lctrMstDiscoverAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) * * \param pOp Originating operation. * \param pAdvBuf Received advertising buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrMstDiscoverAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) @@ -372,7 +369,7 @@ bool_t lctrMstScanRspRxCompHandler(BbOpDesc_t *pOp, const uint8_t *pRspBuf) /* scanReqAdvAddr is assigned when LL_PDU_ADV_SCAN_IND is received. */ if (lctrMstScan.data.disc.scanReqAdvAddr != pScan->filtResults.peerAddr) { - LL_TRACE_WARN0("Ignore scan_rsp since advAddr doesn't match the one sent in the scan_req."); + LL_TRACE_WARN0("Ignore SCAN_RSP due to mismatched advAddr in SCAN_REQ"); break; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master_ae.c index 2869ae5904f..1be7be1d3c6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_master_ae.c @@ -1,28 +1,30 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller master advertising event ISR callbacks. + * \file + * + * \brief Link layer controller master advertising event ISR callbacks. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "lctr_int_adv_master_ae.h" #include "lctr_int_conn_master.h" +#include "lctr_api_bis_master.h" #include "sch_api.h" #include "sch_api_ble.h" #include "bb_ble_api_reslist.h" @@ -78,13 +80,51 @@ struct { bool_t filtResult; /*!< PDU filter result, filter out if TRUE, FAlSE otherwise. */ bool_t syncWithSlave; /*!< Flag indicating synchronize packet received from slave. */ - uint32_t firstRxStartTs; /*!< Timestamp of the first received frame regardless of CRC error. */ + uint32_t firstRxStartTsUsec; /*!< Timestamp in microseconds of the first received frame regardless of CRC error. */ } lctrMstPerScanIsr; /************************************************************************************************** Functions: Utility functions **************************************************************************************************/ +/*************************************************************************************************/ +/*! + * \brief Notify host of BIG Info + * + * \param syncHandle Sync handle. + * \param pBigInfo BIG info. + */ +/*************************************************************************************************/ +static void lctrNotifyHostBigInfoAdvReport(uint16_t syncHandle, LctrAcadBigInfo_t *pBigInfo) +{ + LlBigInfoAdvRptInd_t evt; + + /* Clear not required; all values are written. */ + /* memset(&evt, 0, sizeof(LlBigInfoAdvRptInd_t)); */ + + evt.hdr.param = syncHandle; + evt.hdr.event = LL_BIG_INFO_ADV_REPORT_IND; + evt.hdr.status = LL_SUCCESS; + + evt.syncHandle = syncHandle; + evt.numBis = pBigInfo->numBis; + evt.nse = pBigInfo->nse; + evt.isoInterv = pBigInfo->isoInter; + evt.bn = pBigInfo->bn; + evt.pto = pBigInfo->pto; + evt.irc = pBigInfo->irc; + evt.maxPdu = pBigInfo->maxPdu; + evt.sduInterv = pBigInfo->sduInterUsec; + evt.maxSdu = pBigInfo->maxSdu; + evt.phy = pBigInfo->phy; + evt.framing = pBigInfo->framing; + evt.encrypt = pBigInfo->encrypt; + + LL_TRACE_INFO1("### LlEvent ### LL_BIG_INFO_ADV_REPORT_IND, syncHandle=%u", syncHandle); + + LmgrSendEvent((LlEvt_t *)&evt); +} + /*************************************************************************************************/ /*! * \brief Get the local ID address. @@ -95,8 +135,6 @@ struct * \param pLocalIdAddrType Storage for local ID address type; * \param peerIdAddr Peer ID address. * \param peerIdAddrType Peer ID address type. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrGetLocalIdAddr(lctrExtScanCtx_t *pExtScanCtx, uint64_t targetAddr, @@ -144,50 +182,157 @@ static inline void lctrGetLocalIdAddr(lctrExtScanCtx_t *pExtScanCtx, uint64_t ta /*************************************************************************************************/ /*! - * \brief Master Acad handler. + * \brief Check if the received BIG Info are valid. * - * \param pPerScanCtx Periodic scan context. + * \param pBigInfo BIG Info. * - * \return None + * \return TRUE if parameter is valid, FALSE otherwise. */ /*************************************************************************************************/ -void lctrMstAcadHandler(lctrPerScanCtx_t * const pPerScanCtx) +static bool_t lctrIsBigInfoParamsValid(LctrAcadBigInfo_t *pBigInfo) { - if (pPerScanCtx->extAdvHdr.acadLen == 0) + const uint8_t MIN_NUM_BIS = 0x01; + const uint8_t MAX_NUM_BIS = 0x1F; + const uint32_t MIN_SDU_INTERVAL = 0x00100; + const uint32_t MAX_SDU_INTERVAL = 0xFFFFF; + const uint16_t MIN_ISO_INTERVAL = 0x0004; + const uint16_t MAX_ISO_INTERVAL = 0x0C80; + const uint8_t MIN_NUM_NSE = 0x01; + const uint8_t MAX_NUM_NSE = 0x1F; + const uint16_t MAX_SDU = 0x0FFF; + const uint8_t MIN_PDU = 0x01; + const uint8_t MAX_PDU = 0xFB; + const uint8_t MAX_PHY = 0x02; + const uint8_t MAX_FRAMING = 0x01; + const uint8_t MIN_BN = 0x01; + const uint8_t MAX_BN = 0x07; + const uint8_t MIN_IRC = 0x01; + const uint8_t MAX_IRC = 0x0F; + const uint8_t MAX_PTO = 0x0F; + + if ((pBigInfo->numBis < MIN_NUM_BIS) || (pBigInfo->numBis > MAX_NUM_BIS)) + { + LL_TRACE_WARN1("numBis=%u out of range", pBigInfo->numBis); + return FALSE; + } + if ((pBigInfo->sduInterUsec < MIN_SDU_INTERVAL) || (pBigInfo->sduInterUsec > MAX_SDU_INTERVAL)) { - return; + LL_TRACE_WARN1("sduInterval=%u out of range", pBigInfo->sduInterUsec); + return FALSE; + } + if ((pBigInfo->isoInter < MIN_ISO_INTERVAL) || (pBigInfo->isoInter > MAX_ISO_INTERVAL)) + { + LL_TRACE_WARN1("isoInterval=%u out of range", pBigInfo->isoInter); + return FALSE; + } + if ((pBigInfo->nse < MIN_NUM_NSE) || (pBigInfo->nse > MAX_NUM_NSE)) + { + LL_TRACE_WARN1("NSE=%u out of range", pBigInfo->nse); + return FALSE; + } + if (pBigInfo->maxSdu > MAX_SDU) + { + LL_TRACE_WARN1("maxSdu=%u out of range", pBigInfo->maxSdu); + return FALSE; + } + if ((pBigInfo->maxPdu < MIN_PDU) || (pBigInfo->maxPdu > MAX_PDU)) + { + LL_TRACE_WARN1("maxPdu=%u out of range", pBigInfo->maxPdu); + return FALSE; + } + if ((pBigInfo->phy - 1) > MAX_PHY) + { + LL_TRACE_WARN1("phy=%u out of range", (pBigInfo->phy - 1)); + return FALSE; + } + if (pBigInfo->framing > MAX_FRAMING) + { + LL_TRACE_WARN1("framing=%u out of range", pBigInfo->framing); + return FALSE; + } + if ((pBigInfo->bn < MIN_BN) || (pBigInfo->bn > MAX_BN)) + { + LL_TRACE_WARN1("BN=%u out of range", pBigInfo->bn); + return FALSE; + } + if ((pBigInfo->irc < MIN_IRC) || (pBigInfo->irc > MAX_IRC)) + { + LL_TRACE_WARN1("IRC=%u out of range", pBigInfo->irc); + return FALSE; + } + if (pBigInfo->pto > MAX_PTO) + { + LL_TRACE_WARN1("PTO=%u out of range", pBigInfo->pto); + return FALSE; } - /* Enable any new Acad if necessary */ + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Master ACAD handler. + * + * \param pPerScanCtx Periodic scan context. + */ +/*************************************************************************************************/ +static void lctrMstAcadHandler(lctrPerScanCtx_t * const pPerScanCtx) +{ uint8_t len = pPerScanCtx->extAdvHdr.acadLen; - uint8_t *pBuf = (uint8_t *) pPerScanCtx->extAdvHdr.pAcad; - while(len > 0) + const uint8_t *pBuf = pPerScanCtx->extAdvHdr.pAcad; + + while (len > 0) { - uint8_t acadLen = 0; + uint8_t acadLen; BSTREAM_TO_UINT8(acadLen, pBuf); - uint8_t opcode = 0; + uint8_t opcode; BSTREAM_TO_UINT8(opcode, pBuf); - switch (opcode) { - case LL_ACAD_OPCODE_CHANNEL_MAP_UPDATE: + switch (opcode) + { + case LL_ACAD_OPCODE_CHAN_MAP_UPD: { lctrAcadParam_t *pAcadParam = &pPerScanCtx->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE]; + pAcadParam->hdr.len = acadLen; + pAcadParam->hdr.opcode = opcode; if (pAcadParam->hdr.state == LCTR_ACAD_STATE_DISABLED) { pAcadParam->hdr.state = LCTR_ACAD_STATE_ENABLED; - - BSTREAM_TO_UINT40(pAcadParam->chanMapUpdate.chanMask, pBuf); - BSTREAM_TO_UINT16(pAcadParam->chanMapUpdate.instant, pBuf); + lctrUnpackAcadChanMapUpd(&pAcadParam->chanMapUpdate, pBuf); } break; } + case LL_ACAD_OPCODE_BIG_INFO: + { + lctrAcadParam_t *pAcadParam = &pPerScanCtx->acadParams[LCTR_ACAD_ID_BIG_INFO]; + pAcadParam->hdr.len = acadLen; + pAcadParam->hdr.opcode = opcode; + if (pAcadParam->hdr.state == LCTR_ACAD_STATE_DISABLED) + { + lctrUnpackAcadBigInfo(&pAcadParam->bigInfo, pBuf, acadLen); + if (lctrIsBigInfoParamsValid(&pAcadParam->bigInfo)) + { + pAcadParam->hdr.state = LCTR_ACAD_STATE_ENABLED; + + lctrNotifyHostBigInfoAdvReport(LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx), &pAcadParam->bigInfo); + } + else + { + pAcadParam->hdr.state = LCTR_ACAD_STATE_DISABLED; + } + } + break; + } default: + LL_TRACE_WARN2("Unknown ACAD received: opcode=%u acadLen=%u", opcode, len); + break; } - len -= (acadLen + 1); /* Minus the Acad plus the acadLen field. */ + + len -= acadLen + LL_ACAD_LEN_FIELD_LEN; } } @@ -609,8 +754,6 @@ static inline bool_t lctrPerAdvRptPackTruncate(BbOpDesc_t *pOp, const uint8_t *p * \brief Scan backoff maintenance when response reception is successful. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrScanBackoffRspSuccess(lctrExtScanCtx_t *pExtScanCtx) @@ -638,8 +781,6 @@ void lctrScanBackoffRspSuccess(lctrExtScanCtx_t *pExtScanCtx) * \brief Scan backoff maintenance when response reception failed. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ static void lctrScanBackoffRspFailed(lctrExtScanCtx_t *pExtScanCtx) @@ -727,7 +868,7 @@ bool_t lctrMstDiscoverRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf switch (advHdr.pduType) { case LL_PDU_ADV_EXT_IND: - /* FIXME Check if secondary PHY is supported. */ + /* TODO Check if secondary PHY is supported. */ break; default: /* Legacy advertising. */ @@ -745,8 +886,6 @@ bool_t lctrMstDiscoverRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf * * \param pOp Originating operation. * \param pAdvBuf Received advertising buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) @@ -783,7 +922,7 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t { if ((extAdvHdrFlags & LL_EXT_HDR_ADV_ADDR_BIT) == 0) { - LL_TRACE_WARN0("Ignoring LL_PDU_ADV_EXT_IND due to missing mandatory advA when there is no auxiliary packet."); + LL_TRACE_WARN0("Ignoring LL_PDU_ADV_EXT_IND due to missing mandatory advA when there is no auxiliary packet"); lctrMstExtScanIsr.filtResult = TRUE; break; } @@ -800,7 +939,7 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pScan->filtResults) == FALSE) { - LL_TRACE_WARN0("Ignoring LL_PDU_ADV_EXT_IND due to PDU filtering."); + LL_TRACE_WARN0("EXT_ADV_IND failed BbBleExtPduFiltCheck"); lctrMstExtScanIsr.filtResult = TRUE; break; } @@ -904,16 +1043,16 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t pOp->minDurUsec = 0; /* Update primary scan BOD min duration so that secondary scan can be scheduled. */ lctrUnpackAuxPtr(&pExtScanCtx->priChAuxPtr, pExtScanCtx->extAdvHdr.pAuxPtr); - uint32_t endTs = pScan->advStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + pScan->filtResults.pduLen)); - lctrMstAuxDiscoverOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, pScan->advStartTs, endTs); + uint32_t endTs = pScan->advStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + pScan->filtResults.pduLen); + lctrMstAuxDiscoverOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, pScan->advStartTsUsec, endTs); if ((pExtScanCtx->auxOpPending == FALSE) && (lctrPerCreateSync.state == LCTR_CREATE_SYNC_STATE_DISCOVER) && (lctrMstPerScanIsr.filtResult == FALSE)) { /* Reset the flag if cannot schedule the auxiliary operation. */ - LL_TRACE_WARN0("Reset filter flag due to auxiliary operation scheduling conflict."); + LL_TRACE_WARN0("Reset filter flag due to auxiliary operation scheduling conflict"); lctrMstPerScanIsr.filtResult = TRUE; } @@ -953,6 +1092,8 @@ void lctrMstDiscoverRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t uint64_t peerIdAddr = 0; uint8_t peerIdAddrType = 0; + memset(&pExtScanCtx->extAdvHdr, 0, sizeof(pExtScanCtx->extAdvHdr)); + BbBlePduFiltResultsGetPeerIdAddr(&pScan->filtResults, &peerIdAddr, &peerIdAddrType); LlExtAdvReportInd_t * const pRpt = &pExtScanCtx->data.scan.advRpt; @@ -1038,7 +1179,7 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf /* AdvA is mandatory. */ if ((lctrMstExtScanIsr.extAdvHdrFlags & LL_EXT_HDR_ADV_ADDR_BIT) == 0) { - LL_TRACE_WARN0("Ignoring LL_PDU_AUX_ADV_IND due to missing mandatory advA."); + LL_TRACE_WARN0("Ignoring LL_PDU_AUX_ADV_IND due to missing mandatory AdvA"); lctrMstExtScanIsr.filtResult = TRUE; break; } @@ -1055,7 +1196,7 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pAuxScan->filtResults) == FALSE) { - LL_TRACE_INFO1("Ignoring LL_PDU_AUX_ADV_IND due to PDU filtering, SID=%u", pExtScanCtx->extAdvHdr.sid); + LL_TRACE_WARN0("EXT_ADV_IND failed BbBleExtPduFiltCheck"); lctrMstExtScanIsr.filtResult = TRUE; /* Continue processing for sync establishment filter even when scan filtering failed. */ } @@ -1129,10 +1270,10 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf /*** Save peer periodic advertising parameters. ***/ pPerScanCtx->eventCounter = pExtScanCtx->secSyncInfo.eventCounter; pPerScanCtx->initEventCounter = pExtScanCtx->secSyncInfo.eventCounter; - pPerScanCtx->perInter = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(pExtScanCtx->secSyncInfo.syncInter)); + pPerScanCtx->perInterUsec = LCTR_PER_INTER_TO_US(pExtScanCtx->secSyncInfo.syncInter); pPerScanCtx->sca = pExtScanCtx->secSyncInfo.sca; pPerScanCtx->rxPhys = lctrConvertAuxPtrPhyToBbPhy(pExtScanCtx->priChAuxPtr.auxPhy); - pPerScanCtx->skipInter = pPerScanCtx->perInter * pPerScanCtx->skip; + pPerScanCtx->skipInterUsec = pPerScanCtx->perInterUsec * pPerScanCtx->skip; if (advAMatch == TRUE) { @@ -1146,9 +1287,9 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf pPerScanCtx->trsfAddrType = lctrMstExtScanIsr.advHdr.txAddrRnd; } - uint32_t endTs = pAuxScan->auxStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, pAuxScan->txAuxReqLen)); - lctrMstPerScanOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, &pExtScanCtx->secSyncInfo, pAuxScan->auxStartTs, endTs); + uint32_t endTs = pAuxScan->auxStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, pAuxScan->txAuxReqLen); + lctrMstPerScanOpCommit(pExtScanCtx, &pExtScanCtx->priChAuxPtr, &pExtScanCtx->secSyncInfo, pAuxScan->auxStartTsUsec, endTs); lctrMstPerScanIsr.syncWithSlave = FALSE; } break; @@ -1179,7 +1320,7 @@ bool_t lctrMstDiscoverRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf { if (!pAuxScan->filtResults.peerMatch) { - /* Require peer match. */ + LL_TRACE_WARN0("AUX_ADV_IND failed peer match"); lctrMstExtScanIsr.filtResult = TRUE; return FALSE; } @@ -1299,7 +1440,7 @@ bool_t lctrMstDiscoverRxAuxScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBu if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pAuxScan->filtResults) == FALSE) { - LL_TRACE_WARN0("LL_PDU_AUX_SCAN_RSP failed PDU filtering."); + LL_TRACE_WARN0("LL_PDU_AUX_SCAN_RSP failed PDU filtering"); lctrMstExtScanIsr.filtResult = TRUE; return FALSE; } @@ -1314,7 +1455,7 @@ bool_t lctrMstDiscoverRxAuxScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBu /* scanReqAdvAddr is assigned when LL_PDU_ADV_SCAN_IND is received. */ if (pExtScanCtx->data.scan.scanReqAdvAddr != pAuxScan->filtResults.peerAddr) { - LL_TRACE_WARN0("Ignore AUX_SCAN_RSP since advAddr doesn't match the one sent in the AUX_SCAN_REQ."); + LL_TRACE_WARN0("Ignore AUX_SCAN_RSP since advAddr doesn't match the one sent in the AUX_SCAN_REQ"); lctrMstExtScanIsr.filtResult = TRUE; return FALSE; } @@ -1431,6 +1572,7 @@ bool_t lctrMstDiscoverRxAuxChainPostProcessHandler(BbOpDesc_t *pOp, const uint8_ bool_t result = TRUE; /*** Report generation. ***/ + if (lctrMstExtScanIsr.filtResult) { /* No further processing for filtered PDUs. */ @@ -1654,7 +1796,7 @@ bool_t lctrMstDiscoverRxLegacyScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRs /* scanReqAdvAddr is assigned when LL_PDU_ADV_SCAN_IND is received. */ if (pExtScanCtx->data.scan.scanReqAdvAddr != pScan->filtResults.peerAddr) { - LL_TRACE_WARN0("Ignore scan_rsp since advAddr doesn't match the one sent in the scan_req."); + LL_TRACE_WARN0("Ignore scan_rsp since advAddr doesn't match the one sent in the scan_req"); break; } @@ -1700,79 +1842,106 @@ bool_t lctrMstDiscoverRxLegacyScanRspHandler(BbOpDesc_t *pOp, const uint8_t *pRs * \brief Reschedule primary scan operation. * * \param pExtScanCtx Extended scan context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtDiscoverReschedule(lctrExtScanCtx_t *pExtScanCtx) { + lctrExtScanCtx_t *pNextScanCtx = pExtScanCtx; BbOpDesc_t *pOp = &pExtScanCtx->scanBod; - BbBleData_t * const pBle = pOp->prot.pBle; - BbBleMstAdvEvent_t * const pScan = &pBle->op.mstAdv; + BbBleData_t *pBle = pOp->prot.pBle; + BbBleMstAdvEvent_t *pScan = &pBle->op.mstAdv; + uint8_t scanPhyIndex = (LCTR_GET_EXT_SCAN_HANDLE(pExtScanCtx) == LCTR_SCAN_PHY_CODED) ? LCTR_SCAN_PHY_CODED : LCTR_SCAN_PHY_1M; /*** Reschedule primary operation ***/ - /* Recover primary scan BOD min duration so that its run will be guaranteed in BB. */ - pOp->minDurUsec = LCTR_MIN_SCAN_USEC; - /* Reset due time to start of scan window. */ - pOp->due = pExtScanCtx->scanWinStart; + pOp->dueUsec = pExtScanCtx->scanWinStartUsec; + + /* Recover primary scan BOD min duration if it was set to 0 to yield to aux BOD. */ + pOp->minDurUsec = LCTR_MIN_SCAN_USEC; if ((pExtScanCtx->scanParam.scanInterval != pExtScanCtx->scanParam.scanWindow) && ((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow))) { - const uint32_t min = BB_US_TO_BB_TICKS(pScan->elapsedUsec); - const uint32_t max = BB_BLE_TO_BB_TICKS(pExtScanCtx->scanParam.scanWindow); + const uint32_t min = pScan->elapsedUsec; + const uint32_t max = LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow) - LCTR_MIN_SCAN_USEC; - if (SchInsertEarlyAsPossible(pOp, min, max)) + if (min <= max) { - /* Continue interrupted operation. */ - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pExtScanCtx->scanWinStart); - WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); - return; + if (SchInsertEarlyAsPossible(pOp, min, max)) + { + /* Continue interrupted operation. */ + pScan->elapsedUsec = pOp->dueUsec - pExtScanCtx->scanWinStartUsec; + WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); + return; + } } } /* Advance to next scanInterval. */ - pScan->elapsedUsec = 0; + /* Decide which scan context BOD will run next. */ + /* If aborted, continue running the aborted BOD. */ + if (pExtScanCtx->bodAborted == FALSE) + { + uint8_t index; - /* Compute next channel. */ - pBle->chan.chanIdx = lctrScanChanSelectNext(pBle->chan.chanIdx, pScan->scanChMap); + WSF_ASSERT((lctrActiveExtScan.scanMask & LCTR_VALID_ACTIVE_SCAN_MASK) != 0); - if (pExtScanCtx->scanParam.scanInterval == pExtScanCtx->scanParam.scanWindow) + for (index = 0; index < LCTR_SCAN_PHY_TOTAL; index++) + { + scanPhyIndex++; + if (scanPhyIndex >= LCTR_SCAN_PHY_TOTAL) + { + scanPhyIndex = LCTR_SCAN_PHY_1M; + } + + if (lctrActiveExtScan.scanMask & (1 << scanPhyIndex)) + { + lctrActiveExtScan.scanIndex = scanPhyIndex; + + pNextScanCtx = LCTR_GET_EXT_SCAN_CTX(scanPhyIndex); + pOp = &pNextScanCtx->scanBod; + pBle = pOp->prot.pBle; + pScan = &pBle->op.mstAdv; + break; + } + } + + /* Compute next channel. */ + pBle->chan.chanIdx = lctrScanChanSelectNext(pBle->chan.chanIdx, pScan->scanChMap); + } + + pScan->elapsedUsec = 0; + + if (pNextScanCtx->scanParam.scanInterval == pNextScanCtx->scanParam.scanWindow) { - /* Continuous scan. */ + /* Continuous scan, move to the next scan window. */ SchInsertNextAvailable(pOp); - pExtScanCtx->scanWinStart = pOp->due; + pNextScanCtx->scanWinStartUsec = pOp->dueUsec; } else { - /* Next scan interval. */ - const uint32_t min = BB_BLE_TO_BB_TICKS(pExtScanCtx->scanParam.scanInterval); - const uint32_t max = min + BB_BLE_TO_BB_TICKS(pExtScanCtx->scanParam.scanWindow); - - while (TRUE) + if (!(lctrActiveExtScan.bodSchMask & (1 << scanPhyIndex))) { - /* Store start of next scan window. */ - pExtScanCtx->scanWinStart = pOp->due + min; - - if (SchInsertEarlyAsPossible(pOp, min, max)) - { - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pExtScanCtx->scanWinStart); - WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); - break; - } - else - { - /* Advance to next scan window. */ - pOp->due = pExtScanCtx->scanWinStart; + /* Due time is not initialized for this BOD yet. */ + SchInsertNextAvailable(pOp); + pNextScanCtx->scanWinStartUsec = pOp->dueUsec; + lctrActiveExtScan.bodSchMask |= (1 << scanPhyIndex); + } + else + { + /* Move to next scan interval. */ + pOp->dueUsec += LCTR_BLE_TO_US(pNextScanCtx->scanParam.scanInterval); + pNextScanCtx->scanWinStartUsec = pOp->dueUsec; + (void)SchInsertEarlyAsPossible(pOp, 0, LCTR_SCH_MAX_SPAN); - LL_TRACE_WARN1("!!! Scan schedule conflict at due=%u", pOp->due + min); - LL_TRACE_WARN1("!!! scanWindowUsec=%u", LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow)); - } + /* Align the scan interval. If elapsedUsec is over the window size, BB will not execute the BOD. */ + pScan->elapsedUsec = pOp->dueUsec - pNextScanCtx->scanWinStartUsec; } } + + pNextScanCtx->bodAborted = FALSE; } /*************************************************************************************************/ @@ -1780,13 +1949,12 @@ static void lctrMstExtDiscoverReschedule(lctrExtScanCtx_t *pExtScanCtx) * \brief End a discovery scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtDiscoverEndOp(BbOpDesc_t *pOp) { lctrExtScanCtx_t * const pExtScanCtx = pOp->pCtx; + const uint8_t scanPhyIndex = (LCTR_GET_EXT_SCAN_HANDLE(pExtScanCtx) == LCTR_SCAN_PHY_CODED) ? LCTR_SCAN_PHY_CODED : LCTR_SCAN_PHY_1M; if (pExtScanCtx->shutdown || pExtScanCtx->selfTerm) { @@ -1794,6 +1962,7 @@ void lctrMstExtDiscoverEndOp(BbOpDesc_t *pOp) if (( pExtScanCtx->auxOpPending && (pExtScanCtx->bodTermCnt >= 2)) || /* Wait for both ExtScan and AuxScan operations. */ (!pExtScanCtx->auxOpPending && (pExtScanCtx->bodTermCnt >= 1))) /* Wait only for ExtScan operation. */ { + lctrActiveExtScan.scanMask &= ~(1 << scanPhyIndex); lctrSendExtScanMsg(pExtScanCtx, LCTR_EXT_SCAN_MSG_TERMINATE); } return; @@ -1811,21 +1980,39 @@ void lctrMstExtDiscoverEndOp(BbOpDesc_t *pOp) /* else postpone until lctrMstAuxDiscoverEndOp(). */ } +/*************************************************************************************************/ +/*! + * \brief Abort a discovery scan operation in the master role. + * + * \param pOp Aborted operation. + */ +/*************************************************************************************************/ +void lctrMstExtDiscoverAbortOp(BbOpDesc_t *pOp) +{ + lctrExtScanCtx_t * const pExtScanCtx = pOp->pCtx; + + WSF_ASSERT(pOp->protId == BB_PROT_BLE); + WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_MST_ADV_EVENT); + + pExtScanCtx->bodAborted = TRUE; + lctrMstExtDiscoverEndOp(pOp); +} + /*************************************************************************************************/ /*! * \brief End an auxiliary discovery scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstAuxDiscoverEndOp(BbOpDesc_t *pOp) { lctrExtScanCtx_t * const pExtScanCtx = pOp->pCtx; + const uint8_t scanPhyIndex = (LCTR_GET_EXT_SCAN_HANDLE(pExtScanCtx) == LCTR_SCAN_PHY_CODED) ? LCTR_SCAN_PHY_CODED : LCTR_SCAN_PHY_1M; if (pExtScanCtx->shutdown || pExtScanCtx->selfTerm) { + lctrActiveExtScan.scanMask &= ~(1 << scanPhyIndex); lctrSendExtScanMsg(pExtScanCtx, LCTR_EXT_SCAN_MSG_TERMINATE); return; } @@ -1845,8 +2032,6 @@ void lctrMstAuxDiscoverEndOp(BbOpDesc_t *pOp) * \brief End an periodic scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) @@ -1880,7 +2065,7 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) if ((pPerScanCtx->eventCounter - pPerScanCtx->initEventCounter) == (fastTermCnt - 1)) { - LL_TRACE_ERR0("!!! lctrMstPerScanEndOp: Failed to receive AUX_SYNC_IND within first 6 intervals."); + LL_TRACE_ERR0("!!! lctrMstPerScanEndOp: Failed to receive AUX_SYNC_IND within first 6 intervals"); /* Notify create sync state machine with sync failed. */ lctrSendCreateSyncMsg(pPerScanCtx, LCTR_CREATE_SYNC_MSG_FAILED); } @@ -1893,14 +2078,14 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) if (lctrMstPerScanIsr.syncWithSlave) { /* Re-sync with advertiser */ - pPerScanCtx->lastAnchorPoint = lctrMstPerScanIsr.firstRxStartTs; + pPerScanCtx->lastAnchorPointUsec = lctrMstPerScanIsr.firstRxStartTsUsec; lctrMstPerScanIsr.syncWithSlave = FALSE; pPerScanCtx->lastActiveEvent = pPerScanCtx->eventCounter; /* Reset supervision timer. */ WsfTimerStartMs(&pPerScanCtx->tmrSupTimeout, pPerScanCtx->syncTimeOutMs); - if (pPerScanCtx->skipInter && - pPerScanCtx->skipInter < BB_US_TO_BB_TICKS(pPerScanCtx->syncTimeOutMs * 1000)) + if (pPerScanCtx->skipInterUsec && + pPerScanCtx->skipInterUsec < pPerScanCtx->syncTimeOutMs * 1000) { /* Skip is set and shorter than the sync timeout. */ skip = pPerScanCtx->skip; @@ -1920,13 +2105,13 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) while (TRUE) { - /* Handle Acad if any pending actions are waiting. */ + /* Handle ACAD if any pending actions are waiting. */ lctrAcadMsg_t acadMsg; acadMsg.hdr.eventCtr = pPerScanCtx->eventCounter; acadMsg.hdr.skip = skip; acadMsg.hdr.handle = LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx); - for (uint8_t acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) + for (unsigned int acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) { if (pPerScanCtx->acadParams[acadId].hdr.state != LCTR_ACAD_STATE_DISABLED) { @@ -1938,17 +2123,14 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) pPerScanCtx->eventCounter += skip; numUnsyncIntervals += skip; - uint32_t unsyncTimeUsec = BB_TICKS_TO_US(pPerScanCtx->perInter * numUnsyncIntervals); + uint32_t unsyncTimeUsec = pPerScanCtx->perInterUsec * numUnsyncIntervals; uint32_t caPpm = lctrCalcTotalAccuracy(pPerScanCtx->sca); uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, caPpm); - uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec); - uint32_t connInterUsec = BB_TICKS_TO_US(numUnsyncIntervals * pPerScanCtx->perInter); - uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec); - int16_t dueOffsetUsec = (connInterUsec - wwTotalUsec) - BB_TICKS_TO_US(connInter - wwTotal); + uint32_t connInterUsec = numUnsyncIntervals * pPerScanCtx->perInterUsec; /* Advance to next interval. */ - pOp->due = pPerScanCtx->lastAnchorPoint + connInter - wwTotal; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + pOp->dueUsec = pPerScanCtx->lastAnchorPointUsec + connInterUsec - wwTotalUsec; + pOp->minDurUsec = pPerScanCtx->minDurUsec + wwTotalUsec; pBle->op.mstPerScan.rxSyncDelayUsec = pPerScanCtx->rxSyncDelayUsec + (wwTotalUsec << 1); @@ -1967,8 +2149,6 @@ void lctrMstPerScanEndOp(BbOpDesc_t *pOp) * \brief Abort an periodic scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstPerScanAbortOp(BbOpDesc_t *pOp) @@ -2022,7 +2202,7 @@ uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBu if (lctrPerTransferSync.state == LCTR_TRANSFER_SYNC_STATE_DISCOVER) { - pPerScanCtx->skipInter = pPerScanCtx->perInter * pPerScanCtx->skip; + pPerScanCtx->skipInterUsec = pPerScanCtx->perInterUsec * pPerScanCtx->skip; } } @@ -2031,14 +2211,38 @@ uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBu (pMstPerScan->perIsFirstTs == TRUE) && (status == BB_STATUS_SUCCESS)) { - lctrMstPerScanIsr.firstRxStartTs = pMstPerScan->perStartTs; + lctrMstPerScanIsr.firstRxStartTsUsec = pMstPerScan->perStartTsUsec; lctrMstPerScanIsr.syncWithSlave = TRUE; } /*** ACAD processing. ***/ + lctrMstAcadHandler(pPerScanCtx); + LctrAcadBigInfo_t *pBigInfo = &pPerScanCtx->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + + if (pBigInfo->hdr.state == LCTR_ACAD_STATE_ENABLED) + { + pBigInfo->bigAnchorPoint = pMstPerScan->perStartTsUsec + + (pBigInfo->bigOffs * ((pBigInfo->bigOffsUnits == 0) ? 30 : 300)); + + /* TODO: Use ACAD state machine instead of direct message to BIG. + * Periodic Master should not know about BIG contexts. */ + LctrBigInfoMsg_t *pMsg; + if ((pMsg = WsfMsgAlloc(sizeof(LctrBigInfoMsg_t))) != NULL) + { + pMsg->hdr.handle = 0; + pMsg->hdr.dispId = LCTR_DISP_BIG_SYNC; + pMsg->hdr.event = 3; /* LCTR_MST_BIG_ACAD_BIG_INFO */ + + memcpy(&pMsg->data, pBigInfo, sizeof(pMsg->data)); + + WsfMsgSend(lmgrPersistCb.handlerId, &pMsg->hdr); + } + } + /*** Periodic Advertising Data processing. ***/ + uint32_t auxOffsetUsec = 0; if (lctrMstExtScanIsr.extAdvHdrFlags & LL_EXT_HDR_AUX_PTR_BIT) { @@ -2060,7 +2264,7 @@ uint32_t lctrMstPerScanRxPerAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBu * \param pOp Originating operation. * \param pAdvBuf Advertising buffer. * - * \return None + * \return TRUE if report generated, FALSE if not. */ /*************************************************************************************************/ bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) @@ -2143,8 +2347,6 @@ bool_t lctrMstPerScanRxPerAdvPktPostHandler(BbOpDesc_t *pOp, const uint8_t *pAdv /*************************************************************************************************/ /*! * \brief Initialize periodic scan ISR context. - * - * \return None */ /*************************************************************************************************/ void lctrMstPerScanIsrInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave.c index 185e31b9da1..979cdefa25b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -67,8 +68,6 @@ bool_t lctrScanReqHandler(BbOpDesc_t *pOp, uint8_t reqLen) * \param pOp Originating operation. * \param reqLen Request packet length. * \param pReqBuf Received request buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrConnIndHandler(BbOpDesc_t *pOp, uint8_t reqLen, const uint8_t *pReqBuf) @@ -129,8 +128,8 @@ bool_t lctrSlvAdvHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) case LL_PDU_CONNECT_IND: /* BOD must be terminated before setting up the next operation. */ lctrConnIndHandler(pOp, pduLen, pReqBuf); - lctrSlvAdv.reqEndTs = pAdv->reqStartTs + - BB_US_TO_BB_TICKS(LCTR_CONN_IND_PKT_1M_US); /* N.B.: may round to an earlier time */ + lctrSlvAdv.reqEndTsUsec = pAdv->reqStartTsUsec + + LCTR_CONN_IND_PKT_1M_US; /* Requirement for peer address match will be enforced in action handler. */ break; @@ -147,8 +146,6 @@ bool_t lctrSlvAdvHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) * * \param pOp Originating operation. * \param pReqBuf Received request buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAdvPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) @@ -196,8 +193,6 @@ void lctrSlvAdvPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) * \brief End an advertising operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAdvEndOp(BbOpDesc_t *pOp) @@ -330,28 +325,28 @@ void lctrSlvAdvEndOp(BbOpDesc_t *pOp) { /* maxDelay is 16, it times 625 still fits in uint32_t. */ /* coverity[overflow_before_widen] */ - pOp->due += BB_BLE_TO_BB_TICKS(lctrCalcAdvDelay()); + pOp->dueUsec += BB_BLE_TO_US(lctrCalcAdvDelay()); } - if (lmgrSlvAdvCb.advParam.advInterMin == lmgrSlvAdvCb.advParam.advInterMax) + if (lmgrSlvAdvCb.advParam.advInterMinUsec == lmgrSlvAdvCb.advParam.advInterMaxUsec) { - pOp->due += lmgrSlvAdvCb.advParam.advInterMin; + pOp->dueUsec += lmgrSlvAdvCb.advParam.advInterMinUsec; result = SchInsertAtDueTime(pOp, NULL); } else { result = SchInsertEarlyAsPossible(pOp, - lmgrSlvAdvCb.advParam.advInterMin, - lmgrSlvAdvCb.advParam.advInterMax); + lmgrSlvAdvCb.advParam.advInterMinUsec, + lmgrSlvAdvCb.advParam.advInterMaxUsec); if (!result) { - pOp->due += lmgrSlvAdvCb.advParam.advInterMax; + pOp->dueUsec += lmgrSlvAdvCb.advParam.advInterMaxUsec; } } if (!result) { - LL_TRACE_WARN1("!!! Adv schedule conflict at due=%u", pOp->due); + LL_TRACE_WARN1("!!! Adv schedule conflict at dueUsec=%u", pOp->dueUsec); LL_TRACE_WARN1("!!! minDurUsec=%u", pOp->minDurUsec); } @@ -361,32 +356,32 @@ void lctrSlvAdvEndOp(BbOpDesc_t *pOp) } case LL_ADV_CONN_DIRECT_HIGH_DUTY: { - uint32_t advEventStart = pOp->due; - uint32_t advTermCntDown = lmgrSlvAdvCb.advTermCntDown; + uint32_t advEventStart = pOp->dueUsec; + uint32_t advTermCntDown = lmgrSlvAdvCb.advTermCntDownUsec; bool_t result = FALSE; - while (!result && lmgrSlvAdvCb.advTermCntDown) + while (!result && lmgrSlvAdvCb.advTermCntDownUsec) { - result = SchInsertLateAsPossible(pOp, lmgrSlvAdvCb.advParam.advInterMin, lmgrSlvAdvCb.advParam.advInterMax); + result = SchInsertLateAsPossible(pOp, lmgrSlvAdvCb.advParam.advInterMinUsec, lmgrSlvAdvCb.advParam.advInterMaxUsec); if (!result) { - pOp->due += lmgrSlvAdvCb.advParam.advInterMax; + pOp->dueUsec += lmgrSlvAdvCb.advParam.advInterMaxUsec; } - uint32_t advEventDur = pOp->due - advEventStart; + uint32_t advEventDur = BbGetTargetTimeDelta(pOp->dueUsec, advEventStart); - if ((advEventDur + lmgrSlvAdvCb.advParam.advInterMax) < advTermCntDown) + if ((advEventDur + lmgrSlvAdvCb.advParam.advInterMaxUsec) < advTermCntDown) { - lmgrSlvAdvCb.advTermCntDown = advTermCntDown - advEventDur; + lmgrSlvAdvCb.advTermCntDownUsec = advTermCntDown - advEventDur; } else { /* Terminate at end of next advertising event. */ - lmgrSlvAdvCb.advTermCntDown = 0; + lmgrSlvAdvCb.advTermCntDownUsec = 0; } } - if (!result && !lmgrSlvAdvCb.advTermCntDown) + if (!result && !lmgrSlvAdvCb.advTermCntDownUsec) { lctrMsgHdr_t *pMsg; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave_ae.c index 5dd5ab9eb00..69db9834b3d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave extended advertising ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave extended advertising ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -56,19 +57,17 @@ static lctrScanReq_t lctrAdvIsrScanReq; /*! * \brief Transmit setup complete for an extended advertising primary channel operation. * - * \param pOp Completed operation. - * \param advTxTime Start time of advertising packet. - * - * \return None. + * \param pOp Completed operation. + * \param advTxTimeUsec Start time of advertising packet in microseconds. */ /*************************************************************************************************/ -void lctrSlvTxSetupExtAdvHandler(BbOpDesc_t *pOp, uint32_t advTxTime) +void lctrSlvTxSetupExtAdvHandler(BbOpDesc_t *pOp, uint32_t advTxTimeUsec) { lctrAdvSet_t * const pAdvSet = pOp->pCtx; if (pAdvSet->pExtAdvAuxPtr && pAdvSet->auxBodUsed) { - uint32_t auxOffsetUsec = BB_TICKS_TO_US(pAdvSet->auxAdvBod.due - advTxTime); + uint32_t auxOffsetUsec = BbGetTargetTimeDelta(pAdvSet->auxAdvBod.dueUsec, advTxTimeUsec); /* Compute EXT_ADV_IND PDU OTA time. */ uint32_t txAdvUsec; @@ -176,6 +175,32 @@ uint32_t lctrSlvTxSetupPeriodicAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd /* Compute new chanIdx for next chain packet. */ lctrSelectNextPerChannel(pAdvSet); + /* Update BIG Info timing values. */ + LctrAcadBigInfo_t * const pBigInfo = &pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + if (pBigInfo->hdr.state == LCTR_ACAD_STATE_ENABLED) + { + uint32_t bigOffsUsec = pBigInfo->bigAnchorPoint - pOp->dueUsec; + + if (bigOffsUsec < 600) + { + bigOffsUsec += pBigInfo->isoInter * 1250; + pBigInfo->bisPldCtr += pBigInfo->nse; + } + + if (bigOffsUsec < 491460) + { + /* use 30us units */ + pBigInfo->bigOffsUnits = 0; + pBigInfo->bigOffs = LL_MATH_DIV_30(bigOffsUsec); + } + else + { + /* use 300us units */ + pBigInfo->bigOffsUnits = 1; + pBigInfo->bigOffs = LL_MATH_DIV_300(bigOffsUsec); + } + } + pPerAdv->txAuxAdvPdu[0].len = lctrPackSyncIndPdu(pAdvSet, pAdvSet->perAdvHdrBuf, &pAdvSet->perAdvData, TRUE); /* Set initial fragment. */ @@ -187,7 +212,7 @@ uint32_t lctrSlvTxSetupPeriodicAdvDataHandler(BbOpDesc_t *pOp, bool_t isChainInd /* Store/use current AuxPtr values. */ uint16_t advDataOffs = pAdvSet->perAdvData.txOffs; - /* Compute new chanIdx for next chainpacket if there is any. */ + /* Compute new chanIdx for next chain packet if there is any. */ if (pAdvSet->perAdvData.txOffs < pAdvSet->perAdvData.len) { lctrSelectNextPerChannel(pAdvSet); @@ -302,7 +327,6 @@ bool_t lctrSlvRxAuxScanReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pAuxAdv->filtResults) == FALSE) { - LL_TRACE_WARN0("Ignoring LL_PDU_AUX_SCAN_REQ due to PDU filtering."); return FALSE; } @@ -315,8 +339,6 @@ bool_t lctrSlvRxAuxScanReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) * * \param pOp Originating operation. * \param pReqBuf Received request buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvRxAuxScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) @@ -332,7 +354,7 @@ void lctrSlvRxAuxScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqB BbBlePduFiltResultsGetPeerIdAddr(&pAuxAdv->filtResults, &peerIdAddr, &peerIdAddrType); - // TODO Offload report to task context. + /* TODO Offload report to task context. */ LmgrSendScanReqReceivedInd(pAdvSet->handle, peerIdAddrType, peerIdAddr); @@ -345,8 +367,6 @@ void lctrSlvRxAuxScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqB * * \param pOp Originating operation. * \param pReqBuf Received request buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvRxLegacyScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) @@ -362,7 +382,7 @@ void lctrSlvRxLegacyScanReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pR BbBlePduFiltResultsGetPeerIdAddr(&pAdv->filtResults, &peerIdAddr, &peerIdAddrType); - // TODO Offload report to task context. + /* TODO Offload report to task context. */ LmgrSendScanReqReceivedInd(pAdvSet->handle, peerIdAddrType, peerIdAddr); @@ -412,7 +432,6 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pAuxAdv->filtResults) == FALSE) { - LL_TRACE_WARN0("Ignoring LL_PDU_AUX_CON_REQ due to PDU filtering."); return sendRsp; } @@ -474,10 +493,9 @@ bool_t lctrSlvRxAuxConnReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) /*** Received advertising PDU post-processing. ***/ pAdvSet->usedChSel = LL_CH_SEL_2; /* LL_PDU_AUX_CONNECT_REQ always uses Channel Selection #2. */ - pAdvSet->connIndEndTs = pAuxAdv->auxReqStartTs + - /* N.B.: May round to an earlier time. */ - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, - LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN)); + pAdvSet->connIndEndTsUsec = pAuxAdv->auxReqStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, + LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); sendRsp = TRUE; } @@ -540,8 +558,6 @@ bool_t lctrSlvRxLegacyReqHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) * * \param pOp Originating operation. * \param pReqBuf Received request buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBuf) @@ -571,8 +587,8 @@ void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBu pAdvSet->usedChSel = LL_CH_SEL_1; } - pAdvSet->connIndEndTs = pAdv->reqStartTs + - BB_US_TO_BB_TICKS(LCTR_CONN_IND_PKT_1M_US); /* N.B.: May round to an earlier time. */ + pAdvSet->connIndEndTsUsec = pAdv->reqStartTsUsec + + LCTR_CONN_IND_PKT_1M_US; break; default: break; @@ -581,39 +597,40 @@ void lctrSlvRxLegacyReqPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pReqBu /*************************************************************************************************/ /*! - * \brief Acad handler for post op. + * \brief ACAD handler for post op. * * \param pAdvSet Advertising Set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet) { - for (uint8_t acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) + for (unsigned int acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) { - lctrAcadParam_t *pData = &pAdvSet->acadParams[acadId]; + lctrAcadParam_t *pAcad = &pAdvSet->acadParams[acadId]; - if (pData->hdr.state != LCTR_ACAD_STATE_ENABLED) + if (pAcad->hdr.state != LCTR_ACAD_STATE_ENABLED) { continue; } /* coverity[dead_error_condition] */ - switch(acadId) + switch (acadId) { case LCTR_ACAD_ID_CHAN_MAP_UPDATE: { - if (pData->chanMapUpdate.instant == pAdvSet->perParam.perEventCounter) + if (pAcad->chanMapUpdate.instant == pAdvSet->perParam.perEventCounter) { /* Update the channel map. */ - pAdvSet->perParam.perChanParam.chanMask = pData->chanMapUpdate.chanMask; + pAdvSet->perParam.perChanParam.chanMask = pAcad->chanMapUpdate.chanMask; LmgrBuildRemapTable(&pAdvSet->perParam.perChanParam); /* Disable the ACAD. */ lctrSlvAcadExecuteSm(pAdvSet, LCTR_ACAD_MSG_CHAN_UPDATE_FINISH); - /* If the most updated channel map does not match the current mask, start a new update. */ + /* Update Channel Map in BIG Info. */ + pAcad->bigInfo.chanMap = pAdvSet->perParam.perChanParam.chanMask; + + /* Check for updated Channel Map. */ if (pAdvSet->perParam.perChanParam.chanMask != pAdvSet->perParam.updChanMask) { lctrSlvAcadExecuteSm(pAdvSet, LCTR_ACAD_MSG_CHAN_UPDATE); @@ -622,6 +639,18 @@ void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet) break; } + case LCTR_ACAD_ID_BIG_INFO: + { + /* Updated in lctrSlvAcadHandler(), upon Channel Map changes. */ + /* pAcad->bigInfo.chanMap = pAdvSet->perParam.perChanParam.chanMask; */ + + /* Updated in lctrSlvBigEndOp(), upon timing changes. */ + /* pAcad->bigInfo.bigAnchorPoint = pOp->dueUsec; */ + /* pAcad->bigInfo.bisPldCtr = pBigCtx->eventCounter; */ + + break; + } + default: break; } @@ -637,8 +666,6 @@ void lctrSlvAcadHandler(lctrAdvSet_t *pAdvSet) * \brief End an extended advertising primary channel operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) @@ -698,6 +725,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) } /*** Update advertising data ***/ + if ((pAdvSet->param.advEventProp & LL_ADV_EVT_PROP_LEGACY_ADV_BIT) == 0) { /* Update superior PDU including AdvA and TgtA. */ @@ -721,7 +749,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) } } - /* Schedule aux BOD if periodic advertisng is enabled. */ + /* Schedule auxiliary BOD if periodic advertising is enabled. */ if ((pAdvSet->perParam.perAuxStart == TRUE) && pAdvSet->perParam.perAdvEnabled && pAdvSet->pExtAdvAuxPtr && @@ -741,7 +769,6 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) } else /* (pAdvSet->param.advEventProp & LL_ADV_EVT_PROP_LEGACY_ADV_BIT) */ { - /* Update local private address. */ bool_t update = FALSE; uint64_t newAddr = 0; @@ -841,38 +868,39 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) SchBleCalcAdvOpDuration(pOp, 0); /*** Reschedule operation ***/ + const uint8_t LEGACY_HIGH_DUTY = (LL_ADV_EVT_PROP_LEGACY_ADV_BIT | LL_ADV_EVT_PROP_HIGH_DUTY_ADV_BIT | LL_ADV_EVT_PROP_DIRECT_ADV_BIT | LL_ADV_EVT_PROP_CONN_ADV_BIT); if ((pAdvSet->param.advEventProp & LEGACY_HIGH_DUTY) == LEGACY_HIGH_DUTY) { { - uint32_t advEventStart = pOp->due; - uint32_t advTermCntDown = pAdvSet->param.priAdvTermCntDown; + uint32_t advEventStartUsec = pOp->dueUsec; + uint32_t advTermCntDown = pAdvSet->param.priAdvTermCntDownUsec; bool_t result = FALSE; - while (!result && pAdvSet->param.priAdvTermCntDown) + while (!result && pAdvSet->param.priAdvTermCntDownUsec) { - result = SchInsertLateAsPossible(pOp, pAdvSet->param.priAdvInterMin, pAdvSet->param.priAdvInterMax); + result = SchInsertLateAsPossible(pOp, pAdvSet->param.priAdvInterMinUsec, pAdvSet->param.priAdvInterMaxUsec); if (!result) { - pOp->due += pAdvSet->param.priAdvInterMax; + pOp->dueUsec += pAdvSet->param.priAdvInterMaxUsec; } - uint32_t advEventDur = pOp->due - advEventStart; + uint32_t advEventDur = BbGetTargetTimeDelta(pOp->dueUsec, advEventStartUsec); - if ((advEventDur + pAdvSet->param.priAdvInterMax) < advTermCntDown) + if ((advEventDur + pAdvSet->param.priAdvInterMaxUsec) < advTermCntDown) { - pAdvSet->param.priAdvTermCntDown = advTermCntDown - advEventDur; + pAdvSet->param.priAdvTermCntDownUsec = advTermCntDown - advEventDur; } else { /* Terminate at end of next advertising event. */ - pAdvSet->param.priAdvTermCntDown = 0; + pAdvSet->param.priAdvTermCntDownUsec = 0; } } - if (!result && !pAdvSet->param.priAdvTermCntDown) + if (!result && !pAdvSet->param.priAdvTermCntDownUsec) { pAdvSet->termReason = LL_ERROR_CODE_ADV_TIMEOUT; lctrSendAdvSetMsg(pAdvSet, LCTR_EXT_ADV_MSG_TERMINATE); @@ -882,11 +910,11 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) else { uint32_t totalDuration = pOp->minDurUsec; - uint32_t prefInterval; + uint32_t prefIntervalUsec; if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_DLY)) { - pOp->due += BB_BLE_TO_BB_TICKS(lctrCalcAdvDelay()); + pOp->dueUsec += BB_BLE_TO_US(lctrCalcAdvDelay()); } if (pAdvSet->auxBodUsed) @@ -894,8 +922,8 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) totalDuration += pAdvSet->auxAdvBod.minDurUsec; } - /* Pick an interval so that advertising(primary + aux) BOD would take less than half of total bandwidth. */ - prefInterval = WSF_MAX(BB_US_TO_BB_TICKS(totalDuration * 2), pAdvSet->param.priAdvInterMin); + /* Pick an interval so that advertising (primary + aux) BOD would take less than half of total bandwidth. */ + prefIntervalUsec = WSF_MAX(totalDuration * 2, pAdvSet->param.priAdvInterMinUsec); if (pAdvSet->advBodAbort) { @@ -904,7 +932,7 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) } else { - (void)SchInsertEarlyAsPossible(pOp, prefInterval, LCTR_SCH_MAX_SPAN); + (void)SchInsertEarlyAsPossible(pOp, prefIntervalUsec, LCTR_SCH_MAX_SPAN); } } } @@ -914,8 +942,6 @@ void lctrSlvExtAdvEndOp(BbOpDesc_t *pOp) * \brief Abort an extended advertising primary channel operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvExtAdvAbortOp(BbOpDesc_t *pOp) @@ -931,8 +957,6 @@ void lctrSlvExtAdvAbortOp(BbOpDesc_t *pOp) * \brief End an extended advertising secondary channel operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp) @@ -1048,8 +1072,6 @@ void lctrSlvAuxAdvEndOp(BbOpDesc_t *pOp) * \brief End an periodic advertising channel operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp) @@ -1095,11 +1117,12 @@ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp) while (TRUE) { - pOp->due += pAdvSet->perParam.perAdvInter; + pOp->dueUsec += pAdvSet->perParam.perAdvInterUsec; pAdvSet->perParam.perEventCounter++; - /*** Process ACAD fields if necessary ***/ + /*** Process ACAD fields ***/ + lctrSlvAcadHandler(pAdvSet); pAdvSet->perParam.perChIdx = lctrPeriodicSelectNextChannel(&pAdvSet->perParam.perChanParam, @@ -1109,6 +1132,7 @@ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp) { break; } + LL_TRACE_WARN1("!!! Periodic advertising schedule conflict eventCounter=%u", pAdvSet->perParam.perEventCounter); } } @@ -1118,8 +1142,6 @@ void lctrSlvPeriodicAdvEndOp(BbOpDesc_t *pOp) * \brief Abort an periodic advertising channel operation. * * \param pOp Aborted operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvPeriodicAdvAbortOp(BbOpDesc_t *pOp) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_master.c new file mode 100644 index 00000000000..d253b87311d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_master.c @@ -0,0 +1,937 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller master BIG ISR callbacks. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_master.h" +#include "lctr_int_iso.h" +#include "ll_defs.h" +#include "wsf_trace.h" +#include "util/bstream.h" + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief BIS master ISR control block. */ +static struct +{ + lctrSeCtx_t se; /*!< Subevent context. */ + uint8_t numRcvdPkt; /*!< Number of successfully received packets. */ + bool_t firstRxComp; /*!< First Rx in ISO Event completion flag. */ + bool_t cstf; /*!< BIG Event's valid Control Subevent Transmission Flag. */ + uint8_t cssn; /*!< BIG Event's valid Control Subevent Sequence Number. */ + uint32_t nextSeOffs; /*!< Next subevent time. */ + PalBbBleChan_t *pNextChan;/*!< Next subevent channel. */ + uint8_t *pCtrlBuf; /*!< Received BIS Control PDU buffer. */ + uint8_t *pDataBuf[LL_MAX_BIS][LL_MAX_BN]; + /*!< Received data buffers. */ +} lctrMstBisIsr; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Update loop counters for sequential packing. + * + * \param pBigCtx BIG context. + * + * \return TRUE if more Rx pending, FALSE otherwise. + */ +/*************************************************************************************************/ +static bool_t lctrMstBisLoopCounterSequential(lctrBigCtx_t *pBigCtx) +{ + size_t numSePkts = (pBigCtx->bn * pBigCtx->irc) + lctrMstBisIsr.se.ptIdx; + + /* BIG Event limit (beyond BIS Control SubEvent). */ + + if (lctrMstBisIsr.se.bisEvtIdx >= pBigCtx->numBis) + { + return FALSE; + } + + if (!lctrSlvBisCalcNextIdxSequential(pBigCtx, &lctrMstBisIsr.se, numSePkts)) + { + if (!lctrMstBisIsr.cstf) + { + return FALSE; + } + } + + /* Compute next channel. */ + lctrSeCtx_t nextSe = lctrMstBisIsr.se; + if (lctrSlvBisCalcNextIdxSequential(pBigCtx, &nextSe, numSePkts)) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[nextSe.bisEvtIdx]->chan; + } + else + { + lctrMstBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + /* Compute next packet time. */ + lctrMstBisIsr.nextSeOffs += pBigCtx->subInterUsec; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Update loop counters for interleaved packing. + * + * \param pBigCtx BIG context. + * + * \return TRUE if more Rx pending, FALSE otherwise. + */ +/*************************************************************************************************/ +static bool_t lctrMstBisLoopCounterInterleaved(lctrBigCtx_t *pBigCtx) +{ + size_t numSePkts = (pBigCtx->bn * pBigCtx->irc) + lctrMstBisIsr.se.ptIdx; + + /* BIG Event limit (beyond BIS Control SubEvent). */ + + if (numSePkts > pBigCtx->nse) + { + return FALSE; + } + + if (!lctrSlvBisCalcNextIdxInterleaved(pBigCtx, &lctrMstBisIsr.se, numSePkts)) + { + if (!lctrMstBisIsr.cstf) + { + return FALSE; + } + } + + /* Compute next channel. */ + lctrSeCtx_t nextSe = lctrMstBisIsr.se; + if (lctrSlvBisCalcNextIdxInterleaved(pBigCtx, &nextSe, numSePkts)) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[nextSe.bisEvtIdx]->chan; + } + else + { + lctrMstBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + /* Compute next packet time. */ + lctrMstBisIsr.nextSeOffs += pBigCtx->bisSpaceUsec; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Setup a receive PDU. + * + * \param pBigCtx BIG context. + * \param reAcqSync Re-acquisition of synchronization is needed. + * \param pBuf Unused buffer from last receive operation. + * + * \return TRUE if successful, FALSE if out of memory. + */ +/*************************************************************************************************/ +static bool_t lctrMstBisRxData(lctrBigCtx_t *pBigCtx, bool_t reAcqSync, uint8_t *pBuf) +{ + if ((pBuf == NULL) && + ((pBuf = lctrBisRxIsoDataPduAlloc()) == NULL)) + { + LL_TRACE_WARN2("BIG event flow controlled, bigHandle=%u, ec[15:0]=%u", pBigCtx->handle, pBigCtx->eventCounter); + + /* Flow control BIG Event. */ + return FALSE; + } + + /*** Commit transmission ***/ + + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[lctrMstBisIsr.se.bisEvtIdx]; + BbBleBisRxData(pBuf, LL_ISO_DATA_HDR_LEN + BB_DATA_PLD_MAX_LEN, + pBigCtx->roleData.mst.anchorPoint + lctrMstBisIsr.nextSeOffs, + lctrMstBisIsr.pNextChan, + reAcqSync); + + /*** Post-commit calculation ***/ + + /* Now that channel data is set in BB, compute next channel information. */ + pBisCtx->chan.chanIdx = LmgrSelectNextSubEvtChannel(&pBisCtx->chSelInfo); + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief BIG Control PDU decrypt. + * + * \param pBigCtx BIG context. + * + * \return TRUE if successful, FALSE for MIC failure. + */ +/*************************************************************************************************/ +static bool_t lctrMstBigControlDecrypt(lctrBigCtx_t *pBigCtx) +{ + if (pBigCtx->encrypt && lctrPktDecryptHdlr) + { + uint64_t pktCtr = pBigCtx->eventCounter * pBigCtx->bn; + pBigCtx->ctrChan.enc.pRxPktCounter = &pktCtr; + + if (!lctrPktDecryptHdlr(&pBigCtx->ctrChan.enc, lctrMstBisIsr.pCtrlBuf)) + { + LL_TRACE_ERR0("!!! MIC verification failed on BIS Control PDU"); + lctrBisRxIsoDataPduFree(lctrMstBisIsr.pCtrlBuf); + lctrMstBisIsr.pCtrlBuf = NULL; + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_MIC_FAILED); + return FALSE; + } + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief BIG Control PDU post processing. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrMstBigControlPostProcess(lctrBigCtx_t *pBigCtx) +{ + uint8_t opcode = lctrMstBisIsr.pCtrlBuf[LL_DATA_HDR_LEN]; + + if (!pBigCtx->bcp.actMsk) + { + if (opcode < LL_BIG_OPCODE_MAX) + { + switch (opcode) + { + case LL_BIG_OPCODE_CHAN_MAP_IND: + lctrBisUnpackBigChannelMapInd(&pBigCtx->bcp.chanMapUpd.chanMap, + &pBigCtx->bcp.chanMapUpd.inst, + lctrMstBisIsr.pCtrlBuf + LL_DATA_HDR_LEN); + + if (((uint16_t)(pBigCtx->bcp.chanMapUpd.inst - (uint16_t)pBigCtx->eventCounter)) < 0x8000) + { + pBigCtx->bcp.actMsk |= 1 << opcode; + LL_TRACE_INFO2("BIG Channel Map Procedure, bigHandle=%u, instant=%u", pBigCtx->handle, pBigCtx->bcp.chanMapUpd.inst); + } + else + { + /* Ignore error attempt to remain connected as long as possible. */ + LL_TRACE_WARN1("Invalid BIG Channel Map parameters, bigHandle=%u", pBigCtx->handle); + } + + break; + + case LL_BIG_OPCODE_BIG_TERM_IND: + lctrBisUnpackBigTerminateInd(&pBigCtx->bcp.term.reason, + &pBigCtx->bcp.term.inst, + lctrMstBisIsr.pCtrlBuf + LL_DATA_HDR_LEN); + + if (((uint16_t)(pBigCtx->bcp.term.inst - (uint16_t)pBigCtx->eventCounter)) < 0x8000) + { + pBigCtx->bcp.actMsk |= 1 << opcode; + LL_TRACE_INFO2("BIG Terminate Procedure, bigHandle=%u, instant=%u", pBigCtx->handle, pBigCtx->bcp.term.inst); + } + else + { + /* Terminate regardless of error. */ + pBigCtx->bcp.term.reason = LL_ERROR_CODE_INVALID_LMP_PARAMS; + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_PDU_TERM); + LL_TRACE_WARN1("Invalid BIG Terminate parameters, bigHandle=%u", pBigCtx->handle); + } + + break; + + default: + break; + } + } + } + else + { + LL_TRACE_WARN2("Unexpected overlapped BIS Control Procedure, bigHandle=%u, opcode=%u", pBigCtx->handle, opcode); + } + + lctrBisRxIsoDataPduFree(lctrMstBisIsr.pCtrlBuf); +} + +/*************************************************************************************************/ +/*! + * \brief BIG Control Procedure handler. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrMstBigControlProcedureHandler(lctrBigCtx_t *pBigCtx) +{ + if (pBigCtx->bcp.actMsk) + { + uint16_t inst = (pBigCtx->eventCounter + 1) & 0xFFFF; + + if ((pBigCtx->bcp.actMsk & (1 << LL_BIG_OPCODE_CHAN_MAP_IND)) && + (inst == pBigCtx->bcp.chanMapUpd.inst)) + { + pBigCtx->bcp.actMsk &= ~(1 << LL_BIG_OPCODE_CHAN_MAP_IND); + + lctrRemapBigChannels(pBigCtx, pBigCtx->bcp.chanMapUpd.chanMap); + + LL_TRACE_INFO2("Updated channel map: bigHandle=%u inst=%u", pBigCtx->handle, inst); + } + + if (pBigCtx->bcp.actMsk & (1 << LL_BIG_OPCODE_BIG_TERM_IND)) + /* Does not need to wait for instant. */ + { + /* pBigCtx->bcp.actMsk &= ~(1 << LL_BIG_OPCODE_BIG_TERM_IND); */ /* Not needed. */ + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_PDU_TERM); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief BIS Rx Data PDU consumer. + * + * \param pBigCtx BIG context. + * \param rxEvtCtr Received event counter. + */ +/*************************************************************************************************/ +static void lctrMstBisRxDataPduHandler(lctrBigCtx_t *pBigCtx, uint32_t rxEvtCtr) +{ + uint8_t numHandles = 0; + uint16_t handles[LL_MAX_BIS] = { 0 }; + uint16_t numSdu[LL_MAX_BIS] = { 0 }; + uint64_t pktCtrBase = rxEvtCtr * pBigCtx->bn; + lctrIsoalRxCtx_t *pRxCtx; + + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + pRxCtx = &pBisCtx->roleData.mst.isoalRxCtx; + + uint8_t *pDataPdu; + uint8_t pldCtrOffs; + + while ((pDataPdu = lctrBisDequeueRxDataPdu(pBisCtx, &pldCtrOffs)) != NULL) + { + uint64_t pktCtr = pktCtrBase + pldCtrOffs; + pBisCtx->chan.enc.pRxPktCounter = &pktCtr; + + if (lctrPktDecryptHdlr) + { + if (!lctrPktDecryptHdlr(&pBisCtx->chan.enc, pDataPdu)) + { + LL_TRACE_ERR1("!!! MIC verification failed on bisHandle=%u", pBisCtx->handle); + lctrBisRxIsoDataPduFree(pDataPdu); + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_MIC_FAILED); + return; + } + } + + if (pBisCtx->pBigCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + /* Store payload offset for test transit. */ + pBisCtx->test.util.unframed.payloadOffset = pldCtrOffs; + + lctrBisDataPduHdr_t pduHdr; + lctrBisUnpackDataPduHdr(&pduHdr, pDataPdu); + + /*** Assemble ISO SDU ***/ + + uint8_t * const pIsoSdu = pDataPdu - LCTR_ISO_SDU_START_OFFSET; + + switch (pBisCtx->path) + { + case LL_ISO_DATA_PATH_HCI: + { + lctrIsoHdr_t isoHdr = + { + /* ISO header */ + .handle = pBisCtx->handle, + .len = pduHdr.len, + /* .pb = 0, */ /* assigned below */ + .tsFlag = FALSE, + + /* Data load */ + .ts = 0, + .pktSn = pktCtr, + .sduLen = pduHdr.len, + .ps = LCTR_PS_VALID + }; + + if (pBigCtx->lastPduMissed) + { + pRxCtx->data.unframed.ps = LCTR_PS_INVALID; + } + + switch (pBisCtx->lastLlid) + { + case LL_LLID_ISO_UNF_END_PDU: + { + switch (pduHdr.llid) + { + case LL_LLID_ISO_UNF_END_PDU: + default: + isoHdr.pb = LCTR_PB_COMP; + isoHdr.tsFlag = TRUE; + break; + case LL_LLID_ISO_UNF_CONT_PDU: + isoHdr.pb = LCTR_PB_FIRST; + isoHdr.tsFlag = TRUE; + break; + } + break; + } + case LL_LLID_ISO_UNF_CONT_PDU: + { + switch (pduHdr.llid) + { + case LL_LLID_ISO_UNF_END_PDU: + default: + isoHdr.pb = LCTR_PB_LAST; + break; + case LL_LLID_ISO_UNF_CONT_PDU: + isoHdr.pb = LCTR_PB_CONT; + break; + } + break; + } + default: + LL_TRACE_WARN2("Unexpected LLID recieved; dropping Rx ISO PDU, bigHandle=%u, pktCtr[15:0]=%u", pBigCtx->handle, pktCtr); + WsfMsgFree(pIsoSdu); + continue; + } + + pBisCtx->lastLlid = pduHdr.llid; + + uint8_t hdrLen; + hdrLen = lctrIsoPackHdr(pIsoSdu, &isoHdr); + /* Adjust SDU payload to start immediately after the header. */ + memmove(pIsoSdu + hdrLen, pDataPdu + LL_ISO_DATA_HDR_LEN, isoHdr.sduLen); + + /* Move to temporary queue to collect SDU fragments until complete. */ + if (!lctrIsoUnframedRxSduPendQueue(pRxCtx, pIsoSdu, pBisCtx->handle, isoHdr.sduLen, pduHdr.llid)) + { + break; + } + + /* Complete SDU ready to go out. Empty the temp queue and send it out. */ + uint8_t handlerId; + uint8_t *pSduFrag; + while ((pSduFrag = WsfMsgDeq(&pRxCtx->data.unframed.pendSduQ, &handlerId)) != NULL) + { + lctrBisRxIsoSduEnq(pBisCtx, pSduFrag); + numSdu[numHandles]++; + } + break; + } + + case LL_ISO_DATA_PATH_VS: + { + WSF_ASSERT(lctrCodecHdlr.out); + lctrCodecHdlr.out(pBisCtx->handle, pDataPdu + LL_ISO_DATA_HDR_LEN, pDataPdu[LCTR_ISO_DATA_PDU_LEN_OFFSET], pktCtr); + WsfMsgFree(pIsoSdu); /* TODO Resolve PDU free in Audio layer */ + break; + } + + default: + { + LL_TRACE_WARN2("Data path disabled; dropping Rx ISO PDU, bigHandle=%u, pktCtr[15:0]=%u", pBigCtx->handle, pktCtr); + WsfMsgFree(pIsoSdu); + break; + } + } + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + switch (pBisCtx->path) + { + case LL_ISO_DATA_PATH_HCI: + { + numSdu[numHandles] += lctrAssembleRxFramedSdu(&pBisCtx->roleData.mst.isoalRxCtx, &pBisCtx->roleData.mst.rxIsoSduQ, + pBisCtx->handle, pDataPdu, pDataPdu[LCTR_ISO_DATA_PDU_LEN_OFFSET]); + + break; + } + case LL_ISO_DATA_PATH_VS: + { + WSF_ASSERT(lctrCodecHdlr.out); + + lctrAssembleRxFramedSdu(&pBisCtx->roleData.mst.isoalRxCtx, &pBisCtx->roleData.mst.rxIsoSduQ, + pBisCtx->handle, pDataPdu, pDataPdu[LCTR_ISO_DATA_PDU_LEN_OFFSET]); + + uint8_t *pIsoBuf; + while ((pIsoBuf = lctrBisRxIsoSduDeq(pBisCtx)) != NULL) + { + lctrIsoHdr_t isoHdr; + lctrIsoUnpackHdr(&isoHdr, pIsoBuf); + + lctrCodecHdlr.out(pBisCtx->handle, isoHdr.pSdu, isoHdr.sduLen, pktCtr); + WsfMsgFree(pIsoBuf); /* TODO Resolve PDU free in Audio layer */ + } + break; + } + default: + { + LL_TRACE_WARN2("Data path disabled; dropping Rx ISO PDU, bigHandle=%u, pktCtr[15:0]=%u", pBigCtx->handle, pktCtr); + break; + } + } + lctrBisRxIsoDataPduFree(pDataPdu); + } + } + + if (numSdu[numHandles]) + { + if (!pBisCtx->test.enabled) + { + handles[numHandles] = pBisCtx->handle; + numHandles++; + } + else + { + numSdu[numHandles] = 0; + } + } + } + + if (numHandles) + { + /* Notify host received SDUs. */ + lmgrPersistCb.recvIsoPendCback(numHandles, handles, numSdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief BIS Rx Test payload consumer. + * + * \param pBigCtx BIG context. + * \param rxEvtCtr Received event counter. + */ +/*************************************************************************************************/ +static void lctrMstBisRxTestPduHandler(lctrBigCtx_t *pBigCtx, uint32_t rxEvtCtr) +{ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + + /* Consume data for RX test. */ + if (pBisCtx->test.enabled) + { + if (!pBisCtx->test.term) + { + uint8_t *pTestBuf; + uint32_t expPayloadCtr; + + lctrIsoHdr_t isoHdr; + while ((pTestBuf = lctrBisRxIsoSduDeq(pBisCtx)) != NULL) + { + lctrIsoUnpackHdr(&isoHdr, pTestBuf); + + if (pBigCtx->framing == LL_ISO_PDU_TYPE_FRAMED) + { + if (pBisCtx->test.pendInit) + { + uint8_t *pTestDataBuf = (uint8_t *) isoHdr.pSdu; + BSTREAM_TO_UINT32(pBisCtx->test.util.framed.payloadCtr, pTestDataBuf); + LL_TRACE_INFO1("BIS Framed payload counter initialized to %d", pBisCtx->test.util.framed.payloadCtr); + pBisCtx->test.pendInit = FALSE; + } + + LL_TRACE_INFO1("COUNTER = %d", pBisCtx->test.util.framed.payloadCtr); + expPayloadCtr = pBisCtx->test.util.framed.payloadCtr++; + } + else /* LL_ISO_PDU_TYPE_UNFRAMED */ + { + expPayloadCtr = (rxEvtCtr * pBigCtx->bn) + + pBisCtx->test.util.unframed.payloadOffset; + } + + lctrValidateIsoTestData((uint8_t *)isoHdr.pSdu, isoHdr.sduLen, &pBisCtx->roleData.mst.stats, + pBisCtx->test.pldType, pBigCtx->maxSdu, expPayloadCtr); + WsfMsgFree(pTestBuf); + lctrIsoDataRxIncAvailBuf(1); + } + } + + else + { + /* Terminate ISO Test mode operation. */ + pBisCtx->test.enabled = FALSE; + pBisCtx->test.term = FALSE; + pBisCtx->test.pendInit = FALSE; + pBisCtx->test.util.framed.payloadCtr = 0; + } + } + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Complete a received BIS data buffer. + * + * \param pOp Operation context. + * \param pBuf Receive buffer. + * \param status Receive status. + */ +/*************************************************************************************************/ +void lctrMstBisRxCompletion(BbOpDesc_t *pOp, uint8_t *pBuf, uint8_t status) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + BbBleData_t * const pBle = &pBigCtx->bleData; + BbBleMstBisEvent_t * const pBis = &pBle->op.mstBis; + + bool_t reAcqTrain = FALSE; + + if (status == BB_STATUS_SUCCESS) + { + lctrMstBisIsr.numRcvdPkt++; + } + + if (pBigCtx->state != LCTR_MST_BIG_STATE_SYNCED) + { + BbSetBodTerminateFlag(); + goto RxPostProcess; + } + + switch (status) + { + case BB_STATUS_FAILED: + case BB_STATUS_CANCELED: + /* Continue to next BIG Event. */ + BbSetBodTerminateFlag(); + goto RxPostProcess; + + default: + break; + } + + /* Synchronize BIS Event timing. */ + + if (!lctrMstBisIsr.firstRxComp) + { + lctrMstBisIsr.firstRxComp = TRUE; + + switch (status) + { + case BB_STATUS_SUCCESS: + case BB_STATUS_CRC_FAILED: + /* Store peer's timing info for synchronizing next BIS Events and ISO Events. */ + pBigCtx->roleData.mst.anchorPoint = pBigCtx->roleData.mst.rxSyncTime = pBis->startTsUsec; + break; + + default: + break; + } + } + + /* Handle subevent flags. */ + + lctrBisDataPduHdr_t hdr; + lctrBisUnpackDataPduHdr(&hdr, pBuf); + + switch (status) + { + case BB_STATUS_SUCCESS: + lctrMstBisIsr.cstf = hdr.cstf; + lctrMstBisIsr.cssn = hdr.cssn; + break; + + default: + break; + } + + /* Pend BIS PDU. */ + + if ((status == BB_STATUS_SUCCESS) && + !(hdr.llid == LL_LLID_BIG_CTRL_PDU) && + !((hdr.llid == LL_LLID_ISO_EMPTY_PDU) && (hdr.len == 0)) && /* Ignore Empty PDU */ + (lctrMstBisIsr.pDataBuf[lctrMstBisIsr.se.bisEvtIdx][lctrMstBisIsr.se.burstIdx] == NULL)) /* Ignore duplicate */ + { + /* Pend unique BIS PDU reception. */ + lctrMstBisIsr.pDataBuf[lctrMstBisIsr.se.bisEvtIdx][lctrMstBisIsr.se.burstIdx] = pBuf; + pBuf = NULL; + } + + /* Handle failures. */ + + switch (status) + { + case BB_STATUS_RX_TIMEOUT: + /* Re-acquire the receive train. */ + BbBleBisRxDataReAcq(pBigCtx->roleData.mst.anchorPoint + lctrMstBisIsr.nextSeOffs, + lctrMstBisIsr.pNextChan); + reAcqTrain = TRUE; + pBigCtx->lastPduMissed = TRUE; + break; + + default: + break; + } + + /* Adjust loop counters. */ + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + if (!lctrMstBisLoopCounterInterleaved(pBigCtx)) + { + /* Continue to next BIG Event. */ + BbSetBodTerminateFlag(); + goto RxPostProcess; + } + break; + + case LL_PACKING_SEQUENTIAL: + default: + if (!lctrMstBisLoopCounterSequential(pBigCtx)) + { + /* Continue to next BIG Event. */ + BbSetBodTerminateFlag(); + goto RxPostProcess; + } + break; + } + + /* Receive next SubEvent. */ + + if (lctrMstBisRxData(pBigCtx, reAcqTrain, pBuf)) + { + pBuf = NULL; + } + else + { + BbSetBodTerminateFlag(); + } + + /* Now that next Rx is setup, process the received packet. */ +RxPostProcess: + + switch (status) + { + case BB_STATUS_SUCCESS: + switch (hdr.llid) + { + case LL_LLID_BIG_CTRL_PDU: + if (lctrMstBisIsr.pCtrlBuf != NULL) + { + LL_TRACE_WARN1("Unexpected multiple BIS Control PDU received in a single BIG Event, bigHandle=%u", pBigCtx->handle); + } + else if (hdr.cssn == pBigCtx->bcp.cssn) + { + LL_TRACE_WARN1("Unexpected duplicate BIS Control PDU recieved, bigHandle=%u", pBigCtx->handle); + } + else + { + /* Do not receive future duplicate PDUs. */ + pBigCtx->bcp.cssn = hdr.cssn; + + lctrMstBisIsr.pCtrlBuf = pBuf; + pBuf = NULL; + /* Buffer freed in lctrMstBigEndOp(). */ + } + break; + default: + break; + } + break; + + default: + break; + } + + if (pBuf) + { + /* Free unconsumed Data PDU. */ + lctrBisRxIsoDataPduFree(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief Begin a BIG operation. + * + * \param pOp Begin operation. + */ +/*************************************************************************************************/ +void lctrMstBigBeginOp(BbOpDesc_t *pOp) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + + if (pBigCtx->state != LCTR_MST_BIG_STATE_SYNCED) + { + BbSetBodTerminateFlag(); + return; + } + + memset(&lctrMstBisIsr, 0, sizeof(lctrMstBisIsr)); + + /* Compute next packet time. */ + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + if (pBigCtx->numBis > 1) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[1]->chan; + } + else if (pBigCtx->nse > 1) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[0]->chan; + } + else + { + lctrMstBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + lctrMstBisIsr.nextSeOffs = pBigCtx->bisSpaceUsec; + break; + + case LL_PACKING_SEQUENTIAL: + default: + if (pBigCtx->nse > 1) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[0]->chan; + } + else if (pBigCtx->numBis > 1) + { + lctrMstBisIsr.pNextChan = &pBigCtx->pBisCtx[1]->chan; + } + else + { + lctrMstBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + lctrMstBisIsr.nextSeOffs = pBigCtx->subInterUsec; + break; + } + + lctrMstBisIsr.cstf = TRUE; /* receive Control PDU by default */ + lctrMstBisIsr.cssn = 0xFF; + + if (!lctrMstBisRxData(pBigCtx, FALSE, NULL)) + { + BbSetBodTerminateFlag(); + return; + } +} + +/*************************************************************************************************/ +/*! + * \brief End a BIS operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrMstBigEndOp(BbOpDesc_t *pOp) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + BbBleData_t * const pBle = &pBigCtx->bleData; + BbBleMstBisEvent_t * const pBis = &pBle->op.mstBis; + if (pBigCtx->state != LCTR_MST_BIG_STATE_SYNCED) + { + lctrMstBigSendMsg(pBigCtx, LCTR_MST_BIG_INT_TERMINATED_SYNC); + WsfTimerStop(&pBigCtx->roleData.mst.bigSyncTmr); + return; + } + + /* Enqueue BIS Data PDUs. */ + + uint32_t rxEventCounter = pBigCtx->eventCounter; + + for (unsigned int bisIdx = 0; bisIdx < pBigCtx->numBis; bisIdx++) + { + for (unsigned int bnIdx = 0; bnIdx < pBigCtx->bn; bnIdx++) + { + if (lctrMstBisIsr.pDataBuf[bisIdx][bnIdx]) + { + lctrBisEnqueueRxDataPdu(pBigCtx->pBisCtx[bisIdx], + lctrMstBisIsr.pDataBuf[bisIdx][bnIdx], + bnIdx); /* payload counter offset from rxEventCounter */ + } + } + } + + /* BIG Control procedure. */ + + if (lctrMstBisIsr.pCtrlBuf) + { + if (lctrMstBigControlDecrypt(pBigCtx)) + { + lctrMstBigControlPostProcess(pBigCtx); + } + else + { + goto RxPostProcess; + } + } + + /* Reset synchronization timeout timer. */ + + if (lctrMstBisIsr.numRcvdPkt) + { + WsfTimerStartMs(&pBigCtx->roleData.mst.bigSyncTmr, pBigCtx->roleData.mst.bigSyncTimeoutMs); + } + + /* Setup for next BIG Event. */ + + uint32_t unsyncTimeUsec = pBigCtx->roleData.mst.anchorPoint - pBigCtx->roleData.mst.rxSyncTime; + + while (TRUE) + { + /* Advance to next interval. */ + pBigCtx->eventCounter += 1; + pBigCtx->roleData.mst.anchorPoint += pBigCtx->isoInterUsec; + unsyncTimeUsec += pBigCtx->isoInterUsec; + + uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pBigCtx->roleData.mst.totalAcc) + + pBigCtx->roleData.mst.extraWwUsec; + /* TODO Limit to half the ISO Interval size */ + + pOp->dueUsec = pBigCtx->roleData.mst.anchorPoint - wwTotalUsec; + pBis->rxSyncDelayUsec = wwTotalUsec << 1; /* multiply 2 for before and after BIG Anchor Point */ + + lctrSelectBigChannels(pBigCtx); + lctrMstBigControlProcedureHandler(pBigCtx); + + if (SchInsertAtDueTime(pOp, NULL)) + { + break; + } + + LL_TRACE_WARN2("!!! BIG schedule conflict handle=%u, ec[15:0]=%u", pBigCtx->handle, pBigCtx->eventCounter); + } + +RxPostProcess: + /* Consume ISO Data PDU. */ + + lctrMstBisRxDataPduHandler(pBigCtx, rxEventCounter); + lctrMstBisRxTestPduHandler(pBigCtx, rxEventCounter); + + if (lmgrCb.sendIsoCmplEvt) + { + lctrNotifyHostIsoEventComplete(pBigCtx->handle, (uint32_t) pBigCtx->eventCounter); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_slave.c new file mode 100644 index 00000000000..fc86e93ebc7 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_bis_slave.c @@ -0,0 +1,771 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller slave BIG ISR callbacks. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_slave.h" +#include "lctr_int_bis.h" +#include "lctr_int_iso.h" +#include "ll_defs.h" +#include "wsf_trace.h" + +#if (LL_ENABLE_TESTER) +#include "pal_bb_ble_tester.h" +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Write CSSN value. */ +#define LCTR_BIS_WR_CSSN(v, cssn) (v) = ((v) & 0xE3) | (((cssn) & 0x7) << 2) + +/*! \brief Set CSTF flag. */ +#define LCTR_BIS_SET_CSTF(v) (v) |= (1 << 5) + +/*! \brief Clear CSTF flag. */ +#define LCTR_BIS_CLR_CSTF(v) (v) &= ~(1 << 5) + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief BIS slave ISR control block. */ +static struct +{ + lctrSeCtx_t se; /*!< Subevent context. */ + uint8_t csFlags; /*!< CSSN and CSTF flags. */ + uint8_t emptyPdu[LL_EMPTY_PDU_LEN]; + /*!< Empty PDU buffer. */ + uint8_t numTxFrags[LL_MAX_BIS]; + /*!< Number of fragments transmitted. */ + uint32_t nextSeOffs; /*!< Next subevent time. */ + PalBbBleChan_t *pNextChan;/*!< Next subevent channel. */ + uint8_t *pCtrlBuf; /*!< Transmit BIS Control PDU buffer. */ +} lctrSlvBisIsr; + +/*! \brief Transmit descriptor. */ +PalBbBleTxBufDesc_t lctrSlvBisTxDesc[LL_MAX_BIS][LL_MAX_BN][3]; /* Place outside of lctrSlvBisIsr to reduce memclr(). */ + +/*! \brief Encrypted BIS Control PDU buffer. */ +static uint8_t lctrEncCtrlBuf[32]; /* Place outside of lctrSlvBisIsr to reduce memclr(). */ + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Setup BIS Data PDU for an BIS ISO Event. + * + * \param pBigCtx BIG context. + * \param bisIdx BIS index. + * \param burstIdx Burst index. + */ +/*************************************************************************************************/ +static void lctrSlvBisSetupTxData(lctrBigCtx_t *pBigCtx, uint8_t bisIdx, uint8_t burstIdx) +{ + if (lctrBisTxQueuePeek(pBigCtx->pBisCtx[bisIdx], burstIdx, &lctrSlvBisTxDesc[bisIdx][burstIdx][0]) > 0) + { + lctrSlvBisIsr.numTxFrags[bisIdx]++; + + /* Update Control PDU flags. */ + LCTR_BIS_WR_CSSN(lctrSlvBisTxDesc[bisIdx][burstIdx][0].pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET], pBigCtx->bcp.cssn); + if (lctrSlvBisIsr.pCtrlBuf) + { + LCTR_BIS_SET_CSTF(lctrSlvBisTxDesc[bisIdx][burstIdx][0].pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET]); + } + else + { + LCTR_BIS_CLR_CSTF(lctrSlvBisTxDesc[bisIdx][burstIdx][0].pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET]); + } + } + else + { + /* BIS Empty PDU. */ + lctrSlvBisTxDesc[bisIdx][burstIdx][0].pBuf = lctrSlvBisIsr.emptyPdu; + lctrSlvBisTxDesc[bisIdx][burstIdx][0].len = sizeof(lctrSlvBisIsr.emptyPdu); + lctrSlvBisTxDesc[bisIdx][burstIdx][1].pBuf = NULL; + } +} + +/*************************************************************************************************/ +/*! + * \brief BIG Control PDU decrypt. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrMstBigControlEncrypt(lctrBigCtx_t *pBigCtx) +{ + uint64_t pktCtr = pBigCtx->eventCounter * pBigCtx->bn; + pBigCtx->ctrChan.enc.pTxPktCounter = &pktCtr; + + /* Set the new packet counter for inline encryption. */ + if (lctrSetEncryptPktCountHdlr) + { + lctrSetEncryptPktCountHdlr(&pBigCtx->ctrChan.enc, pktCtr); + } + + if (pBigCtx->encrypt && lctrPktEncryptHdlr) + { + uint16_t len = lctrSlvBisIsr.pCtrlBuf[LCTR_ISO_DATA_PDU_LEN_OFFSET]; + + /* Ensure encryption shadow buffer can hold the contents of the data. */ + WSF_ASSERT((size_t)(LL_DATA_HDR_LEN + len + LL_DATA_MIC_LEN) <= sizeof(lctrEncCtrlBuf)); + + memcpy(lctrEncCtrlBuf, lctrSlvBisIsr.pCtrlBuf, LL_DATA_HDR_LEN + len); + uint8_t *pPld = lctrEncCtrlBuf + LL_DATA_HDR_LEN; + uint8_t *pTrl = pPld + len; + + if (lctrPktEncryptHdlr(&pBigCtx->ctrChan.enc, lctrEncCtrlBuf, pPld, pTrl)) + { + #if (LL_ENABLE_TESTER) + pTrl[0] ^= (llTesterCb.pktMic >> 0) & 0xFF; + pTrl[1] ^= (llTesterCb.pktMic >> 8) & 0xFF; + pTrl[2] ^= (llTesterCb.pktMic >> 16) & 0xFF; + pTrl[3] ^= (llTesterCb.pktMic >> 24) & 0xFF; + #endif + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Transmit a BIS Control PDU. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvBisTxControl(lctrBigCtx_t *pBigCtx) +{ + PalBbBleTxBufDesc_t desc; + + if (pBigCtx->encrypt && lctrPktEncryptHdlr) + { + desc.pBuf = lctrEncCtrlBuf; + } + else + { + desc.pBuf = lctrSlvBisIsr.pCtrlBuf; + } + desc.len = LL_DATA_HDR_LEN + desc.pBuf[LCTR_ISO_DATA_PDU_LEN_OFFSET]; + + /* Update Control PDU flags. */ + LCTR_BIS_WR_CSSN(desc.pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET], pBigCtx->bcp.cssn); + LCTR_BIS_CLR_CSTF(desc.pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET]); + + BbBleBisTxData(&desc, 1, 0, NULL); +} + +/*************************************************************************************************/ +/*! + * \brief Transmit a BIS Data PDU. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvBisTxData(lctrBigCtx_t *pBigCtx) +{ + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[lctrSlvBisIsr.se.bisEvtIdx]; + uint8_t descCnt; + PalBbBleTxBufDesc_t *pTxDesc; + + /* Get BIS Data PDU. */ + + PalBbBleTxBufDesc_t ptoTxDesc; + if (lctrSlvBisIsr.se.ptIdx == 0) + { + pTxDesc = &lctrSlvBisTxDesc[lctrSlvBisIsr.se.bisEvtIdx][lctrSlvBisIsr.se.burstIdx][0]; + + if (pTxDesc[1].pBuf) + { + if (pTxDesc[2].pBuf) + { + descCnt = 3; + } + else + { + descCnt = 2; + } + } + else + { + descCnt = 1; + } + } + else + { + ptoTxDesc.pBuf = lctrSlvBisIsr.emptyPdu; + ptoTxDesc.len = sizeof(lctrSlvBisIsr.emptyPdu); + + pTxDesc = &ptoTxDesc; + descCnt = 1; + } + + /* Commit transmission. */ + +#if (LL_ENABLE_TESTER) + /* Check subevent trigger for access address invalidation. */ + if ((llTesterCb.isoAccAddrSeTrigMask & (1 << lctrSlvBisIsr.se.burstIdx)) && + !llTesterCb.isoAccAddrInvForRx) + { + PalBbTesterInvalidateNextAccAddr(FALSE); + + if (llTesterCb.isoAccAddrInvNumTrig) + { + llTesterCb.isoAccAddrInvNumTrig--; + if (llTesterCb.isoAccAddrInvNumTrig == 0) + { + llTesterCb.isoAccAddrSeTrigMask = 0; + } + } + } +#endif + + BbBleBisTxData(pTxDesc, descCnt, + pBigCtx->bod.dueUsec + lctrSlvBisIsr.nextSeOffs, + lctrSlvBisIsr.pNextChan); + + /* Post-commit calculation. */ + + /* Now that channel data is set in BB, compute next channel information. */ + pBisCtx->chan.chanIdx = LmgrSelectNextSubEvtChannel(&pBisCtx->chSelInfo); +} + +/*************************************************************************************************/ +/*! + * \brief BIS Tx Test payload generator. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvBisTxTestPayloadHandler(lctrBigCtx_t *pBigCtx) +{ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + + if (pBisCtx->test.enabled) + { + if (!pBisCtx->test.term) + { + uint8_t *pIsoBuf; + uint32_t pldCtr; + + if (pBigCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + for (unsigned int j = 0; j < pBigCtx->bn; j++) + { + pldCtr = (pBigCtx->eventCounter * pBigCtx->bn) + j; + if ((pIsoBuf = lctrGenerateIsoTestData(pBisCtx->handle, pBisCtx->test.pldType, + pBigCtx->maxSdu, pldCtr)) != NULL) + { + LctrTxIso(pIsoBuf); + } + else + { + /* Out of memory; gracefully continue execution. */ + return; + } + } + } + + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + pldCtr = pBisCtx->test.util.framed.payloadCtr++; + if ((pIsoBuf = lctrGenerateIsoTestData(pBisCtx->handle, pBisCtx->test.pldType, + pBigCtx->maxSdu, pldCtr)) != NULL) + { + LctrTxIso(pIsoBuf); + } + else + { + /* Out of memory; gracefully continue execution. */ + return; + } + } + } + else + { + /* Terminate ISO Test mode operation. */ + pBisCtx->test.enabled = FALSE; + pBisCtx->test.term = FALSE; + pBisCtx->test.util.framed.payloadCtr = 0; + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Check for pending SDU fragments. + * + * \param pBigCtx BIG context. + * + * SDU fragments may be pending waiting on a missed SDU event. Call the ISOAL PDU assembler to + * obtain any pending data. + */ +/*************************************************************************************************/ +static void lctrSlvCheckPendingSdu(lctrBigCtx_t *pBigCtx) +{ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + + uint8_t *pDataBuf; + + if (pBisCtx->roleData.slv.isoalTxCtx.pendQueueSize == 0) + { + /* No pending SDUs. */ + continue; + } + + if ((pDataBuf = lctrTxIsoDataPduAlloc()) != NULL) + { + lctrIsoHdr_t isoHdr = + { + .handle = pBisCtx->handle, + .tsFlag = FALSE + }; + + if ((isoHdr.sduLen = lctrAssembleTxFramedPdu(&pBisCtx->roleData.slv.isoalTxCtx, pDataBuf, pBisCtx->pBigCtx->maxPdu)) > 0) + { + lctrBisTxIsoPduQueue(pBisCtx, &isoHdr, pDataBuf); + } + else + { + /* Release unused buffer. */ + WsfMsgFree(pDataBuf); + } + } + else + { + LL_TRACE_WARN0("Tx path flow controlled; flush pending SDU queue"); + + uint8_t *pSduBuf; + wsfHandlerId_t temp; + + while ((pSduBuf = WsfMsgDeq(&pBisCtx->roleData.slv.isoalTxCtx.pendingSduQ, &temp)) != NULL) + { + WsfMsgFree(pSduBuf); + lctrIsoSduTxIncAvailBuf(); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief BIG Control Procedure handler. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvBigControlProcedureHandler(lctrBigCtx_t *pBigCtx) +{ + if (pBigCtx->bcp.actMsk) + { + uint16_t inst = (pBigCtx->eventCounter + 1) & 0xFFFF; + + if ((pBigCtx->bcp.actMsk & (1 << LL_BIG_OPCODE_CHAN_MAP_IND)) && + (inst == pBigCtx->bcp.chanMapUpd.inst)) + { + pBigCtx->bcp.actMsk &= ~(1 << LL_BIG_OPCODE_CHAN_MAP_IND); + + lctrRemapBigChannels(pBigCtx, pBigCtx->bcp.chanMapUpd.chanMap); + + LL_TRACE_INFO2("Updated channel map: bigHandle=%u inst=%u", pBigCtx->handle, inst); + + if (pBigCtx->roleData.slv.pAdvSet) + { + /* Re-enable BIG Info transmissions. */ + LctrAcadBigInfo_t *pBigInfo = &pBigCtx->roleData.slv.pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + pBigInfo->chanMap = pBigCtx->bcp.chanMapUpd.chanMap; + pBigInfo->hdr.state = LCTR_ACAD_STATE_ENABLED; + } + } + + /* Resume pending BIG Control Procedure. */ + if (pBigCtx->bcp.actMsk == 0) + { + if (pBigCtx->bcp.pendMsk & (1 << LL_BIG_OPCODE_CHAN_MAP_IND)) + { + pBigCtx->bcp.pendMsk &= ~(1 << LL_BIG_OPCODE_CHAN_MAP_IND); + lctrSlvBigSendMsg(pBigCtx, LCTR_SLV_BIG_MSG_CH_MAP_UPD); + } + else if (pBigCtx->bcp.pendMsk & (1 << LL_BIG_OPCODE_BIG_TERM_IND)) + { + pBigCtx->bcp.pendMsk &= ~(1 << LL_BIG_OPCODE_BIG_TERM_IND); + lctrSlvBigSendMsg(pBigCtx, LCTR_SLV_BIG_MSG_TERMINATE_BIG); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief BIS Tx Data PDU complete handler. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvBisTxDataPduHandler(lctrBigCtx_t *pBigCtx) +{ + /*** Tx completion ***/ + + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + + if (lctrSlvBisIsr.numTxFrags[i]) + { + lctrBisTxQueuePopCleanup(pBisCtx, lctrSlvBisIsr.numTxFrags[i]); + } + } + + lctrNotifyIsoTxComplete(pBigCtx); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Complete a transmitted BIS data buffer using sequential packing. + * + * \param pOp Operation context. + * \param status Transmit status. + */ +/*************************************************************************************************/ +void lctrSlvBisTxCompletionSequential(BbOpDesc_t *pOp, uint8_t status) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + + if (status != BB_STATUS_SUCCESS) + { + LL_TRACE_WARN2("!!! Failed BIG transmission handle=%u ec[15:0]=%u", pBigCtx->handle, pBigCtx->eventCounter); + + BbSetBodTerminateFlag(); + return; + } + + /* BIG Event limit (beyond BIS Control SubEvent). */ + + if (lctrSlvBisIsr.se.bisEvtIdx >= pBigCtx->numBis) + { + BbSetBodTerminateFlag(); + return; + } + + size_t numSePkts = (pBigCtx->bn * pBigCtx->irc) + lctrSlvBisIsr.se.ptIdx; + + if (!lctrSlvBisCalcNextIdxSequential(pBigCtx, &lctrSlvBisIsr.se, numSePkts)) + { + if (lctrSlvBisIsr.pCtrlBuf) + { + lctrSlvBisTxControl(pBigCtx); + } + else + { + BbSetBodTerminateFlag(); + } + return; + } + + /* Compute next channel. */ + lctrSeCtx_t nextSe = lctrSlvBisIsr.se; + if (lctrSlvBisCalcNextIdxSequential(pBigCtx, &nextSe, numSePkts)) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[nextSe.bisEvtIdx]->chan; + } + else + { + lctrSlvBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + /* Compute next packet time. */ + lctrSlvBisIsr.nextSeOffs += pBigCtx->subInterUsec; + + lctrSlvBisTxData(pBigCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Complete a transmitted BIS data buffer using interleaved packing. + * + * \param pOp Operation context. + * \param status Transmit status. + */ +/*************************************************************************************************/ +void lctrSlvBisTxCompletionInterleaved(BbOpDesc_t *pOp, uint8_t status) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + + if (status != BB_STATUS_SUCCESS) + { + LL_TRACE_WARN2("!!! Failed BIG transmission handle=%u ec[15:0]=%u", pBigCtx->handle, pBigCtx->eventCounter); + + BbSetBodTerminateFlag(); + return; + } + + size_t numSePkts = (pBigCtx->bn * pBigCtx->irc) + lctrSlvBisIsr.se.ptIdx; + + /* BIG Event limit (beyond BIS Control SubEvent). */ + + if (numSePkts > pBigCtx->nse) + { + BbSetBodTerminateFlag(); + return; + } + + /* BIS loop. */ + + if (!lctrSlvBisCalcNextIdxInterleaved(pBigCtx, &lctrSlvBisIsr.se, numSePkts)) + { + if (lctrSlvBisIsr.pCtrlBuf) + { + lctrSlvBisTxControl(pBigCtx); + } + else + { + BbSetBodTerminateFlag(); + } + + return; + } + + /* Compute next channel. */ + lctrSeCtx_t nextSe = lctrSlvBisIsr.se; + if (lctrSlvBisCalcNextIdxInterleaved(pBigCtx, &nextSe, numSePkts)) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[nextSe.bisEvtIdx]->chan; + } + else + { + lctrSlvBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + /* Compute next packet time. */ + lctrSlvBisIsr.nextSeOffs += pBigCtx->bisSpaceUsec; + + lctrSlvBisTxData(pBigCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Begin a BIG operation. + * + * \param pOp Begin operation. + */ +/*************************************************************************************************/ +void lctrSlvBigBeginOp(BbOpDesc_t *pOp) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + + memset(&lctrSlvBisIsr, 0, sizeof(lctrSlvBisIsr)); + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + if (pBigCtx->numBis > 1) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[1]->chan; + } + else if (pBigCtx->nse > 1) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[0]->chan; + } + else + { + lctrSlvBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + lctrSlvBisIsr.nextSeOffs = pBigCtx->bisSpaceUsec; + break; + + case LL_PACKING_SEQUENTIAL: + default: + if (pBigCtx->nse > 1) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[0]->chan; + } + else if (pBigCtx->numBis > 1) + { + lctrSlvBisIsr.pNextChan = &pBigCtx->pBisCtx[1]->chan; + } + else + { + lctrSlvBisIsr.pNextChan = &pBigCtx->ctrChan; + } + + lctrSlvBisIsr.nextSeOffs = pBigCtx->subInterUsec; + break; + } + + /* Setup Control PDU */ + lctrSlvBisIsr.pCtrlBuf = lctrBigTxCtrlQueuePeek(pBigCtx); + + /* Pre-pack BIS Empty PDU. */ + lctrBisDataPduHdr_t hdr = + { + .llid = LL_LLID_ISO_EMPTY_PDU, + .cssn = pBigCtx->bcp.cssn, + .cstf = lctrSlvBisIsr.pCtrlBuf != NULL, + .len = 0 + }; + uint8_t *pEmptyPdu = lctrSlvBisIsr.emptyPdu; + lctrBisPackDataPduHdr(pEmptyPdu, &hdr); + + /* Commit first Data PDU. */ + lctrSlvBisSetupTxData(pBigCtx, 0, 0); + lctrSlvBisTxData(pBigCtx); + + /* Now that the first Data PDU is committed, setup remaining Data PDUs. */ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + for (unsigned int j = 0; j < pBigCtx->bn; j++) + { + if (!((i == 0) && (j == 0))) /* skip first Data PDU */ + { + lctrSlvBisSetupTxData(pBigCtx, i, j); + } + } + } + + /* Post setup processing. */ + + if (!pBigCtx->roleData.slv.notifyHostEst) + { + pBigCtx->roleData.slv.notifyHostEst = TRUE; + lctrNotifyHostCreateBigComplete(pBigCtx, LL_SUCCESS); + } + + if (lctrSlvBisIsr.pCtrlBuf) + { + lctrMstBigControlEncrypt(pBigCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief End a BIS operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrSlvBigEndOp(BbOpDesc_t *pOp) +{ + lctrBigCtx_t * const pBigCtx = pOp->pCtx; + + /* Setup for next BIG Event. */ + + while (TRUE) + { + /* Complete BIS Data PDU processing. */ + lctrSlvBisTxDataPduHandler(pBigCtx); + /* TODO Incoming data payloadCounter should match scheduled eventCounter */ + + /* BIS Control PDU accounting. */ + lctrBigTxCtrlQueuePop(pBigCtx); + + if (pBigCtx->state != LCTR_SLV_BIG_STATE_ENABLED) + { + if (pBigCtx->bcp.actMsk & (1 << LL_BIG_OPCODE_BIG_TERM_IND)) + { + /* Ensure delivery of BIG_TERMINATE_IND is complete. */ + if (WsfQueueEmpty(&pBigCtx->roleData.slv.txCtrlQ)) + { + lctrSlvBigSendMsg(pBigCtx, LCTR_SLV_BIG_MSG_TERMINATED); + return; + } + } + else /* Reset */ + { + lctrSlvBigSendMsg(pBigCtx, LCTR_SLV_BIG_MSG_TERMINATED); + return; + } + } + + /* Advance to next interval. */ + pBigCtx->eventCounter += 1; + pOp->dueUsec += pBigCtx->isoInterUsec; + + /* Select next BIS Event channels. */ + lctrSelectBigChannels(pBigCtx); + lctrSlvBigControlProcedureHandler(pBigCtx); + + if (SchInsertAtDueTime(pOp, NULL)) + { + break; + } + + LL_TRACE_WARN2("!!! BIG schedule conflict handle=%u, ec[15:0]=%u", pBigCtx->handle, pBigCtx->eventCounter); + } + + /* SDU generator. */ + + lctrSlvBisTxTestPayloadHandler(pBigCtx); + + /* Update BIG Info. */ + + lctrAdvSet_t * const pAdvSet = pBigCtx->roleData.slv.pAdvSet; + if (pAdvSet) + { + lctrAcadParam_t * const pAcad = &pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO]; + pAcad->bigInfo.bigAnchorPoint = pOp->dueUsec; + pAcad->bigInfo.bisPldCtr = pBigCtx->eventCounter * pBigCtx->bn; + } + + /* SDU queue maintenance. */ + + if (pBigCtx->framing == LL_ISO_PDU_TYPE_FRAMED) + { + lctrSlvCheckPendingSdu(pBigCtx); + } + + /* Notifications. */ + + if (lmgrCb.sendIsoCmplEvt) + { + lctrNotifyHostIsoEventComplete(pBigCtx->handle, (uint32_t) pBigCtx->eventCounter); + } +} + +/*************************************************************************************************/ +/*! + * \brief Abort a BIS operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrSlvBigAbortOp(BbOpDesc_t *pOp) +{ + WSF_ASSERT(pOp->protId == BB_PROT_BLE); + WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_SLV_BIS_EVENT); + + LL_TRACE_WARN1("BIG BOD aborted, eventCounter=%u", ((lctrBigCtx_t *)pOp->pCtx)->eventCounter); + + lctrSlvBigEndOp(pOp); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis.c new file mode 100644 index 00000000000..4cec77a5df1 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis.c @@ -0,0 +1,358 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connected isochronous stream ISR callbacks. + * + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_iso.h" +#include "lctr_int_cis.h" +#include "bb_ble_api.h" +#include "pal_bb.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "util/bstream.h" +#include + +#if (LL_ENABLE_TESTER) +#include "pal_bb_ble_tester.h" +#endif + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief CIS ISR control block. */ +static union +{ + /* Added at top of structure for 32-bit alignment. */ + uint8_t emptyPdu[LL_EMPTY_PDU_LEN]; + /*!< Empty PDU buffer. Used only by active operation. */ + uint32_t align32; /*!< Not used, declared for alignment of emptyPdu. */ +} lctrCisIsr; + +/*************************************************************************************************/ +/*! + * \brief Build empty CIS PDU. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static inline void lctrCisBuildEmptyPdu(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->txHdr.llid = LL_LLID_ISO_EMPTY_PDU; + /* pCisCtx->txHdr.nesn = 0; */ /* FC bits already valid */ + /* pCisCtx->txHdr.sn = 0; */ /* FC bits already valid */ + /* pCisCtx->txHdr.cie = 0; */ /* already set */ + pCisCtx->txHdr.len = 0; + + lctrCisPackDataPduHdr(lctrCisIsr.emptyPdu, &pCisCtx->txHdr); +} + +/*************************************************************************************************/ +/*! + * \brief Build NULL CIS PDU. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static inline void lctrCisBuildNullPdu(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->txHdr.llid = LL_LLID_ISO_UNF_END_PDU; + /* pCisCtx->txHdr.nesn = 0; */ /* FC bits already valid */ + pCisCtx->txHdr.sn = 0; + /* pCisCtx->txHdr.cie = 0; */ /* already set */ + pCisCtx->txHdr.np = 1; + pCisCtx->txHdr.len = 0; + + lctrCisPackDataPduHdr(lctrCisIsr.emptyPdu, &pCisCtx->txHdr); +} + +/*************************************************************************************************/ +/*! + * \brief Set flow control bits in PDU. + * + * \param pHdr Unpacked PDU header. + * \param pBuf Packed packet buffer. + */ +/*************************************************************************************************/ +static inline void lctrCisUpdateFlowCtrlBits(const lctrCisDataPduHdr_t *pHdr, uint8_t *pBuf) +{ + const uint8_t FC_BITMASK = 0xC; + + pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET] &= ~FC_BITMASK; + + pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET] |= (pHdr->nesn & 1) << 2; + pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET] |= (pHdr->sn & 1) << 3; + pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET] |= (pHdr->cie & 1) << 4; + pBuf[LCTR_ISO_DATA_PDU_FC_OFFSET] |= (pHdr->np & 1) << 6; +} + +/*************************************************************************************************/ +/*! + * \brief Process Rx acknowledgment. + * + * \param pCisCtx CIS context. + * + * \return TRUE if peer ACK last Tx PDU, FALSE if peer NACK'ed last PDU. + */ +/*************************************************************************************************/ +bool_t lctrCisProcessRxAck(lctrCisCtx_t *pCisCtx) +{ + bool_t result = FALSE; + + if (pCisCtx->rxHdr.np == 1) + { + /* NULL PDU doesn't need to be acked or processed.*/ + return result; + } + + /* Acknowledgment of received PDU (new data PDU). */ + if (((pCisCtx->rxHdr.sn ^ pCisCtx->txHdr.nesn) & 1) == 0) /* bits are same */ + { + /* Accept packets up to the maximum length because peer may queue packets before length change. */ + if (pCisCtx->rxHdr.len > (pCisCtx->localDataPdu.maxRxLen + LL_DATA_MIC_LEN)) + { + /* Invalid length value; ack PDU but drop it (don't process it). */ + lctrCisIncPacketCounterRx(pCisCtx); + pCisCtx->txHdr.nesn++; + return result; + } + + if ((pCisCtx->rxHdr.len) || + ((pCisCtx->rxHdr.len == 0) && (pCisCtx->rxHdr.llid == LL_LLID_ISO_UNF_END_PDU))) + { + /* lctrCisIncPacketCounterRx(pCisCtx) */ /* done after decryption in lctrCisRxPendingHandler */ + result = TRUE; + } + else /* Empty PDU. */ + { + lctrCisIncPacketCounterRx(pCisCtx); + } + /* Invalid LLID value; ack PDU but drop it (don't process it). */ + /* length of 0 and LLID of LL_LLID_EMPTY_PDU implies padding/empty PDU. */ + + pCisCtx->txHdr.nesn++; + pCisCtx->rxFtParamList.pHead->ftParam.pduRcved = TRUE; + return result; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Last Data PDU acknowledged by peer. + * + * \param pCisCtx Connection context. + */ +/*************************************************************************************************/ +void lctrCisTxPduAck(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->txHdr.len = 0; + pCisCtx->txBufPendAck = FALSE; + + /* Remove last transmitted PDU. */ + if (lctrCisTxQueuePop(pCisCtx)) + { + pCisCtx->txDataCounter++; + } +} + +/*************************************************************************************************/ +/*! + * \brief Process Tx acknowledgment. + * + * \param pCisCtx Connection context. + * + * \return TRUE if peer ACK last Tx PDU, FALSE if peer NACK'ed last PDU. + * + * Free ARQ element on peer acknowledgment. + */ +/*************************************************************************************************/ +bool_t lctrCisProcessTxAck(lctrCisCtx_t *pCisCtx) +{ + if (((pCisCtx->rxHdr.nesn ^ pCisCtx->txHdr.sn) & 1) == 1) /* bits are different */ + { + pCisCtx->txHdr.sn++; + + + if (pCisCtx->txBufPendAck) + { + /*** Peer ACK'ed a data PDU ***/ + + lctrCisTxPduAck(pCisCtx); + } + else + { + /*** Peer ACK'ed an Empty PDU ***/ + + pCisCtx->txDataCounter++; + } + + pCisCtx->txFtParamList.pHead->ftParam.pduAcked = TRUE; + + return TRUE; + } + /* Peer NACK'ed PDU. */ + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Post-process Tx acknowledgment. + * + * \param pCisCtx Connection context. + * + * Cleanup from Tx acknowledgment processing. + */ +/*************************************************************************************************/ +void lctrCisProcessTxAckCleanup(lctrCisCtx_t *pCisCtx) +{ + /* Complete buffer cleanup. */ + if (pCisCtx->txPduIsAcked || pCisCtx->pduFlushed) + { + lctrCisTxQueuePopCleanup(pCisCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Setup for CIS data PDU transmission. + * + * \param pCigCtx Connection context. + * \param rxStatus Status of last receive. + * \param reqTx Require Tx. + * + * \return Number of bytes transmitted, 0 if no packet transmitted. + */ +/*************************************************************************************************/ +uint16_t lctrCisSetupForTx(lctrCigCtx_t *pCigCtx, uint8_t rxStatus, bool_t reqTx) +{ + uint16_t numTxBytes = 0; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + +#if (LL_ENABLE_TESTER) + /* Invalidate access address if trigger is set. */ + if (llTesterCb.isoAccAddrSeTrigMask && + (llTesterCb.isoAccAddrSeTrigMask & (1 << pCisCtx->subEvtCounter)) && + !llTesterCb.isoAccAddrInvForRx) + { + PalBbTesterInvalidateNextAccAddr(FALSE); + + if (llTesterCb.isoAccAddrInvNumTrig) + { + llTesterCb.isoAccAddrInvNumTrig--; + if (llTesterCb.isoAccAddrInvNumTrig == 0) + { + llTesterCb.isoAccAddrSeTrigMask = 0; + } + } + } +#endif + + /*** Setup for transmit ***/ + + /* pCisCtx->txHdr.cie = 0; CIE bit is initialized in the lctrMstCisInitIsr or lctrSlvCisInitIsr and shall be set once for the event. */ + pCisCtx->txHdr.np = 0; + pCisCtx->txHdr.len = 0; + pCisCtx->txHdr.llid = LL_LLID_ISO_UNF_END_PDU; + + if ((rxStatus != BB_STATUS_SUCCESS) || + reqTx) + { + PalBbBleTxBufDesc_t bbDesc[3]; + uint8_t bbDescCnt; + + if (pCisCtx->isTxDone == TRUE) + { + /*** Send NULL PDU ***/ + + lctrCisBuildNullPdu(pCisCtx); + + PalBbBleTxBufDesc_t desc = {.pBuf = lctrCisIsr.emptyPdu, .len = sizeof(lctrCisIsr.emptyPdu)}; + BbBleCisTxData(&desc, 1); + numTxBytes = desc.len; + + return numTxBytes; + } + + /* Do not remove from ARQ until acknowledged by peer. */ + bbDescCnt = lctrCisTxQueuePeek(pCisCtx, &bbDesc[0]); + lctrFtParam_t *pFtParam = &pCisCtx->txFtParamList.pHead->ftParam; + + if (bbDescCnt > 0) + { + /* Set flow control bits. */ + pCisCtx->txHdr.len = bbDesc[0].pBuf[LCTR_ISO_DATA_PDU_LEN_OFFSET]; + pFtParam->pduType[pFtParam->pduCounter] = LCTR_CIS_PDU_NON_EMPTY; + pCisCtx->txBufPendAck = TRUE; + lctrCisUpdateFlowCtrlBits(&pCisCtx->txHdr, bbDesc[0].pBuf); + +#if (LL_ENABLE_TESTER) + bbDesc[0].pBuf[0] ^= llTesterCb.pktLlId & 0x03; +#endif + + BbBleCisTxData(&bbDesc[0], bbDescCnt); + numTxBytes = LL_DATA_HDR_LEN + bbDesc[0].pBuf[LCTR_ISO_DATA_PDU_LEN_OFFSET]; + + if (pCisCtx->subEvtCounter == pCisCtx->nse) + { + pCisCtx->isoLinkQualStats.txLastSubEventPkt++; + } + } + else + { + /*** Send Empty PDU ***/ + + lctrCisBuildEmptyPdu(pCisCtx); + pFtParam->pduType[pFtParam->pduCounter] = LCTR_CIS_PDU_EMPTY; + + PalBbBleTxBufDesc_t desc = {.pBuf = lctrCisIsr.emptyPdu, .len = sizeof(lctrCisIsr.emptyPdu)}; + BbBleCisTxData(&desc, 1); + numTxBytes = desc.len; + } + } + /* else nothing to transmit */ + + return numTxBytes; +} + +/*************************************************************************************************/ +/*! + * \brief Rx post processing. + * + * \param pCisCtx CIS context. + * \param pRxBuf Rx buffer. + */ +/*************************************************************************************************/ +void lctrCisRxPostProcessing(lctrCisCtx_t *pCisCtx, uint8_t *pRxBuf) +{ + if (pCisCtx->validRx) /* Another buffer ready to replace the received one. */ + { + lctrCisRxEnq(pRxBuf, pCisCtx->cisEvtCounter, pCisCtx->cisHandle); + } + else + { + lctrCisRxPduFree(pRxBuf); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_master.c new file mode 100644 index 00000000000..d9708259350 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_master.c @@ -0,0 +1,1205 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller master connected isochronous stream ISR callbacks. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int.h" +#include "lctr_int_cis.h" +#include "lctr_int_cis_master.h" +#include "lctr_int_iso.h" +#include "lmgr_api_conn.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "bb_ble_api.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include "pal_codec.h" + +#if (LL_ENABLE_TESTER) +#include "pal_bb_ble_tester.h" +#endif + +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +#if (LL_ENABLE_TESTER) +void LctrCisProcessRxTxAck(lctrCisCtx_t *pCtx, bool_t *pValidRx, bool_t *pTxPduIsAcked); +#endif + +/*************************************************************************************************/ +/*! + * \brief Initialize master CIS event resources. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrMstCisInitIsr(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->subEvtCounter = 0; + pCisCtx->data.mst.rxFromSlave = FALSE; + pCisCtx->txDataCounter = 0; + pCisCtx->rxDataCounter = 0; + + pCisCtx->txFtParamList.pHead->ftParam.subEvtCounter = 0; + pCisCtx->rxFtParamList.pHead->ftParam.subEvtCounter = 0; + + if (pCisCtx->txFtParamList.pHead->ftParam.bn == 0) + { + pCisCtx->isTxDone = TRUE; + } + else + { + pCisCtx->isTxDone = FALSE; + } + + /*** Setup for transmit ***/ + + pCisCtx->txHdr.cie = 0; + pCisCtx->txHdr.np = 0; + + /*** Setup for receive ***/ + + pCisCtx->rxHdr.cie = 0; + pCisCtx->rxHdr.np = 0; + pCisCtx->rxHdr.len = 0; + pCisCtx->rxHdr.llid = LL_LLID_ISO_UNF_END_PDU; +} + +/*************************************************************************************************/ +/*! + * \brief Setup the resource for the Rx. + * + * \param pCigCtx CIG context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrMstCisSetupRx(lctrCigCtx_t *pCigCtx, lctrCisCtx_t *pCisCtx) +{ + uint8_t *pBuf; + + if (!lmgrIsoCb.availRxBuf) + { + LL_TRACE_ERR1("!!! lctrMstCisSetupRx, RX buffer not available, cisHandle=%u", pCisCtx->cisHandle); + return; /* flow control Rx */ + } + + /*** Setup for receive ***/ + + if ((pBuf = lctrCisRxPduAlloc(pCisCtx->localDataPdu.maxRxLen)) != NULL) + { +#if (LL_ENABLE_TESTER) + /* Invalidate access address if trigger is set. */ + if (llTesterCb.isoAccAddrSeTrigMask && + (llTesterCb.isoAccAddrSeTrigMask & (1 << pCisCtx->subEvtCounter)) && + llTesterCb.isoAccAddrInvForRx) + { + PalBbTesterInvalidateNextAccAddr(TRUE); + + if (llTesterCb.isoAccAddrInvNumTrig) + { + llTesterCb.isoAccAddrInvNumTrig--; + if (llTesterCb.isoAccAddrInvNumTrig == 0) + { + llTesterCb.isoAccAddrSeTrigMask = 0; + } + } + } +#endif + + BbBleCisRxData(pBuf, LCTR_CIS_DATA_PDU_LEN(pCisCtx->localDataPdu.maxRxLen)); + /* Rx may fail; no more important statements in this code path */ + } + else + { + LL_TRACE_ERR1("!!! OOM while initializing receive buffer at start of CE, cisHandle=%u", pCisCtx->cisHandle); + BbSetBodTerminateFlag(); + } +} + +/*************************************************************************************************/ +/*! + * \brief Setup the resource for the Tx. + * + * \param pCigCtx CIG context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrMstCisSetupTx(lctrCigCtx_t *pCigCtx, lctrCisCtx_t *pCisCtx) +{ + (void)lctrCisSetupForTx(pCigCtx, BB_STATUS_SUCCESS /* does not matter */, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief Check Tx flush timeout and flush PDU if necessary after RX. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckTxFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->txHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParam_t *pFtParam = &pCisCtx->txFtParamList.pHead->ftParam; + + if (pFtParam->pduAcked) + { + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + pFtParam->pduCounter++; + lctrCisIncPacketCounterTx(pCisCtx); + } + else + { + /* Check if this is the last interval before FT. */ + if ((pFtParam->intervalCounter + 1) == pFtParam->intervalTotal) + { + if (pFtParam->subEvtCounter == pFtParam->lastSubEvtFt[pFtParam->pduCounter]) + { + /* PDU needs to be flushed. */ + pCisCtx->txHdr.sn++; + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + + if (pFtParam->pduType[pFtParam->pduCounter] == LCTR_CIS_PDU_NON_EMPTY) + { + /* Need to remove from ack queue if non-empty PDU. */ + lctrCisTxPduAck(pCisCtx); + pCisCtx->pduFlushed = TRUE; /* Set the flag, lctrCisProcessTxAckCleanup will be called to do the cleanup later in the lctrMstCisCigPostSubEvt. */ + } + pFtParam->pduCounter++; + lctrCisIncPacketCounterTx(pCisCtx); + pCisCtx->isoLinkQualStats.txUnAckPkt++; + } + } + else /* Implies that a retransmit will happen. */ + { + pCisCtx->isoLinkQualStats.retransmitPkt++; + } + } + + /* Set the flag to send NULL packet. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->txFtParamList); + } + + /* No more data to send, send NULL packet. */ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + pCisCtx->isTxDone = TRUE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check Rx flush timeout and flush PDU if necessary after RX. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckRxFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->rxFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->rxHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParam_t *pFtParam = &pCisCtx->rxFtParamList.pHead->ftParam; + + if (pFtParam->pduRcved) + { + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + pFtParam->pduCounter++; + } + else + { + /* Check if this is the last interval before FT. */ + if ((pFtParam->intervalCounter + 1) == pFtParam->intervalTotal) + { + if (pFtParam->subEvtCounter == pFtParam->lastSubEvtFt[pFtParam->pduCounter]) + { + /* PDU needs to be flushed. */ + pCisCtx->txHdr.nesn++; + lctrCisIncPacketCounterRx(pCisCtx); + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + pFtParam->pduCounter++; + pCisCtx->isoLinkQualStats.rxUnreceivedPkt++; + pCisCtx->isoalRxCtx.pduFlushed = TRUE; + pCisCtx->isoalRxCtx.packetSequence++; + pCisCtx->numRxMissed++; + } + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->rxFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +static void lctrCisCheckTxFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->txHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParamNode_t *pNode = pCisCtx->txFtParamList.pHead; + + /* Increment interval counter for all the node in the list. */ + while (pNode) + { + pNode->ftParam.intervalCounter++; + pNode = pNode->pNext; + } + + /* Only check the head node. */ + lctrFtParam_t *pFtParam = &pCisCtx->txFtParamList.pHead->ftParam; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE && /* If the PDU is not done. */ + pFtParam->intervalCounter == pFtParam->intervalTotal) /* Check if the PDU needs to be flush in this interval. */ + { + pFtParam->isPduDone[i] = TRUE; + pCisCtx->txHdr.sn++; + + if (pFtParam->pduType[i] == LCTR_CIS_PDU_NON_EMPTY) + { + /* Need to remove from ack queue if non-empty PDU. */ + lctrCisTxPduAck(pCisCtx); + lctrCisTxQueuePopCleanup(pCisCtx); + } + pFtParam->pduCounter++; + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + /* pCisCtx->isTxDone = TRUE; No need since BOD is done. */ + lctrCisFtRemoveHead(&pCisCtx->txFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS context. + * + */ +/*************************************************************************************************/ +static void lctrCisCheckRxFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->rxFtParamList)) + { + /* List is empty. */ + return; + } + + lctrFtParamNode_t *pNode = pCisCtx->rxFtParamList.pHead; + + /* Increment interval counter for all the node in the list. */ + while (pNode) + { + pNode->ftParam.intervalCounter++; + pNode = pNode->pNext; + } + + /* Only check the head node */ + lctrFtParam_t *pFtParam = &pCisCtx->rxFtParamList.pHead->ftParam; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE && /* If the PDU is not done. */ + pFtParam->intervalCounter == pFtParam->intervalTotal) /* Check if the PDU needs to be flush in this interval. */ + { + pFtParam->isPduDone[i] = TRUE; + pCisCtx->txHdr.nesn++; + pFtParam->pduCounter++; + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->rxFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after RX. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + lctrCisCheckTxFtAfterRx(pCisCtx); + lctrCisCheckRxFtAfterRx(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +static void lctrCisCheckFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + lctrCisCheckTxFtAfterBod(pCisCtx); + lctrCisCheckRxFtAfterBod(pCisCtx); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Check whether continue the current operation. + * + * \param pOp Operation. + * \param pNewCisCtx A new CIS operation. + * + * \return Offset of the next operation, zero discontinue next operation, otherwise continue. + */ +/*************************************************************************************************/ +uint32_t lctrMstCisCheckContOp(BbOpDesc_t *pOp, bool_t *pNewCisCtx) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + uint32_t delayUsec = pCisCtx->delayUsec; + uint32_t subIntervUsec = pCisCtx->subIntervUsec; + + WSF_ASSERT(pCisCtx); + + BbBleData_t *pBle = &pCisCtx->bleData; + + if (pCigCtx->packing == LL_PACKING_SEQUENTIAL) + { + if (pCisCtx->rxHdr.cie || pCisCtx->txHdr.cie) + { + /* Skip additional sub-events if receive CIE before reaching the NSE */ + if ((pCisCtx->subEvtCounter + 1) < pCisCtx->nse) /* Plus one since subEvtCounter has not been updated yet. */ + { + delayUsec += delayUsec * (pCisCtx->nse - (pCisCtx->subEvtCounter + 1)); + } + + goto SwitchSeq; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + goto SwitchSeq; + } + + if (pCisCtx->txDataCounter >= pCisCtx->bnMToS && pCisCtx->rxDataCounter >= pCisCtx->bnSToM && pCisCtx->isTxDone == TRUE) + { + /* There is no more data to send. */ + pCisCtx->txHdr.cie = 1; + + if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_MST_CIS_NULL_PDU) == FALSE) + { + goto SwitchSeq; + } + } + + pCisCtx->subEvtCounter++; + + if (pCisCtx->subEvtCounter == pCisCtx->nse) + { + /* There is no more subevent. */ + pCisCtx->txHdr.cie = 1; + pCisCtx->cisDone = TRUE; + goto SwitchSeq; + } + + /*** Continue current CIS ***/ + + /* Set next channel index. */ + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + return delayUsec; + +SwitchSeq: + if ((pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx)) == NULL) + { + goto Done; + } + else + { + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + goto Done; + } + + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrMstCisInitIsr(pCisCtx); + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Move the current CIS to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + + return delayUsec; /* Return the offset from the old CIS */ + } + } + else /* LL_PACKING_INTERLEAVED */ + { + uint8_t oriNextSubEvtChanIdx = pCisCtx->nextSubEvtChanIdx; + + if (pCisCtx->rxHdr.cie || pCisCtx->txHdr.cie) + { + pCisCtx->cisDone = TRUE; + goto SwitchInt; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + lctrCisSetCisDone(&pCigCtx->list, pCisCtx); + goto SwitchInt; + } + + if (pCisCtx->txDataCounter >= pCisCtx->bnMToS && pCisCtx->rxDataCounter >= pCisCtx->bnSToM && pCisCtx->isTxDone == TRUE) + { + /* There is no more data to send. */ + pCisCtx->txHdr.cie = 1; + + if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_MST_CIS_NULL_PDU) == FALSE) + { + pCisCtx->cisDone = TRUE; + goto SwitchInt; + } + } + + pCisCtx->subEvtCounter++; + + if (pCisCtx->subEvtCounter == pCisCtx->nse) + { + /* There is no more subevent. */ + pCisCtx->txHdr.cie = 1; + pCisCtx->cisDone = TRUE; + goto SwitchInt; + } + +SwitchInt: + if (lctrCisGetListCount(&pCigCtx->list) == 1) + { + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /*** Continue current CIS ***/ + + /* Set next channel index. */ + pBle->chan.chanIdx = oriNextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + return subIntervUsec; + } + + if ((pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx)) == NULL) + { + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /* End of the list, loop back to the head of the CIS. */ + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->isLoopBack = TRUE; + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Point to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + + return delayUsec; /* Return the offset from the old CIS */ + } + else + { + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + /*** Continue head CIS ***/ + + /* Set next channel index. */ + lctrCisSetCisDone(&pCigCtx->list, pCisCtx); + + lctrCisCtx_t *pNextCtx, *pTempCtx; + uint32_t addDelayUsec = 0; + + pTempCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->pCisCtx = pTempCtx; + pBle = &pTempCtx->bleData; + memcpy(&pBle->chan, &pTempCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pTempCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + pOp->prot.pBle = pBle; + pCigCtx->isLoopBack = TRUE; + + while (pTempCtx) + { + pNextCtx = lctrCisGetNextCis(&pCigCtx->list, pTempCtx); + + if (pNextCtx == NULL) + { + break; + } + + if (pNextCtx == pCisCtx) + { + break; + } + + addDelayUsec += pTempCtx->delayUsec; + pTempCtx = pNextCtx; + } + + return (subIntervUsec - addDelayUsec); + } + + /* TODO need to check whether this pCisCtx->rxHdr.cie || pCisCtx->txHdr.cie and no sending more PDU for this CIS. */ + + /* Get the next CIS in the list. */ + if (pCigCtx->isLoopBack == FALSE) + { + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrMstCisInitIsr(pCisCtx); + } + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Point to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + if (pCigCtx->isLoopBack == FALSE) + { + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + } + else + { + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + } + + return delayUsec; /* Return the offset from the old CIS */ + } + } + +Done: + /* All CISs are done. Set next CIS to the head of the list. */ + pCigCtx->pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pOp->prot.pBle = &pCigCtx->pCisCtx->bleData; + *pNewCisCtx = TRUE; + lctrCisClearCisDone(&pCigCtx->list); + return 0; +} + +/*************************************************************************************************/ +/*! + * \brief Start the CIG operation. + * + * \param pOp Begin operation. + */ +/*************************************************************************************************/ +void lctrMstCisCigBeginOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t *pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + + pCisCtx = pCigCtx->pCisCtx; + pCigCtx->isLoopBack = FALSE; + + /* Need to setup Tx/Rx flush timeout parameter first since some field will be used in the lctrSlvCisInitIsr. */ + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrMstCisInitIsr(pCisCtx); + + lctrMstCisSetupTx(pCigCtx, pCisCtx); + + /* Setup Tx could fail which leads to terminate BOD. */ + if (!BbGetBodTerminateFlag()) + { + lctrMstCisSetupRx(pCigCtx, pCisCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Continue the CIG operation. + * + * \param pOp Begin operation. + */ +/*************************************************************************************************/ +void lctrMstCisCigContOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t *pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + + pCisCtx = pCigCtx->pCisCtx; + + lctrMstCisSetupTx(pCigCtx, pCisCtx); + + /* Setup Tx could fail which leads to terminate BOD. */ + if (!BbGetBodTerminateFlag()) + { + lctrMstCisSetupRx(pCigCtx, pCisCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Post subevent callback, setup for the next subevent channel index. + * + * \param pOp Current operation. + * \param status Status. + */ +/*************************************************************************************************/ +void lctrMstCisCigPostSubEvt(BbOpDesc_t *pOp, uint8_t status) +{ + lctrCigCtx_t *pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + + WSF_ASSERT(pCigCtx); + pCisCtx = pCigCtx->pCisCtx; + + WSF_ASSERT(pCisCtx); + + /* Pre-calculate the next subevent channel. */ + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup a connection operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrMstCisCigCleanupOp(BbOpDesc_t *pOp) +{ + +} + +/*************************************************************************************************/ +/*! + * \brief End a CIG operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrMstCisCigEndOp(BbOpDesc_t *pOp) +{ + /* Pre-resolve common structures for efficient access. */ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + lctrConnCtx_t * pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + WSF_ASSERT(pCisCtx); /* At least one CIS in the CIG. */ + + while (pCisCtx) + { + pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + /* LL_CIS_TERMINATION case */ + if ((pCisCtx->isClosing == TRUE) || + (pConnCtx->enabled == FALSE) || + (lctrResetEnabled == TRUE)) + { + /* This variable set to TRUE means it is a CIS disconnect that requires an event generation. */ + if (pCisCtx->isClosing == TRUE) + { + /* This was a host-initiated termination of the CIS. */ + lctrNotifyHostCisTerm(pCisCtx); + } + + pCisCtx->isClosing = FALSE; + pCigCtx->numCisEsted--; + lctrCleanupCtx(pCisCtx); + } + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + if (pCigCtx->numCisEsted == 0) + { + return; + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + + while (pCisCtx) + { + pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + lctrCisCheckFtAfterBod(pCisCtx); + + /* Process event completion */ + + if (!pCisCtx->connEst && pCisCtx->data.mst.rxFromSlave) + { + WsfTimerStartMs(&pCisCtx->tmrSupTimeout, pCisCtx->supTimeoutMs); + + pCisCtx->connEst = TRUE; + + /* Now that the first CIS has been established, + * notify host of connection establish and + * start the next CIS creation, if needed. + */ + if (lmgrCisMstCb.createCisPend) + { + lctrMstCreateCisDone(pCisCtx); + lctrNotifyHostCisEst(pCisCtx, LL_SUCCESS, pCisCtx->cigSyncDelayUsec); + } + + if (pCisCtx->powerIndReq && lctrSendPowerChangeIndCback) + { + uint8_t txPhy = (pCisCtx->role == LL_ROLE_MASTER) ? pCisCtx->phyMToS : pCisCtx->phySToM; + lctrSendPowerChangeIndCback(pConnCtx, txPhy, 0, pLctrRtCfg->defTxPwrLvl, TRUE); + } + } + else if (pCisCtx->data.mst.rxFromSlave) + { + /* Reset supervision timer. */ + WsfTimerStartMs(&pCisCtx->tmrSupTimeout, pCisCtx->supTimeoutMs); + } + + /* Failed to receive packet within the first 6 intervals. */ + if ((pCisCtx->firstFromPeer == FALSE) && (pCisCtx->cisEvtCounter == LCTR_FAST_TERM_CNT)) + { + LL_TRACE_WARN1("CIS terminated due to fast termination timeout, handle=%d", pCisCtx->cisHandle); + lctrCisStoreConnFailEstablishTerminateReason(pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); + + if (pCigCtx->numCisEsted == 1) + { + /* If the last CIS to close, schedule no more operation. */ + return; + } + } + + /* Terminate connection */ + if (lctrCheckForCisLinkTerm(pCisCtx->aclHandle)) + { + lctrSendCisLlcpMsg(pCisCtx, LCTR_CIS_TERM_EVENT_CIS_TERM); + } + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + + /*** Adjust the anchor point if the head CIS is removed ***/ + + if (pCigCtx->headCisRmved == TRUE) + { + pCigCtx->headCisRmved = FALSE; + + pOp->dueUsec += pCigCtx->offsetUsec; + pCigCtx->offsetUsec = 0; + + BbBleData_t *pBle = &pCisCtx->bleData; + /* Move the current CIS to the head CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + } + + /*** Update txPower ***/ + + pCisCtx->bleData.chan.txPower = LCTR_GET_TXPOWER(pConnCtx, pCisCtx->phyMToS, pCisCtx->bleData.chan.initTxPhyOptions); +#if(LL_ENABLE_TESTER) + pCisCtx->bleData.chan.txPower += pConnCtx->bleData.chan.txPwrOffset; +#endif + + /*** Reschedule operation ***/ + + while (TRUE) + { + /* Advance to next interval. */ + pOp->dueUsec += LCTR_ISO_INT_TO_US(pCigCtx->isoInterval); + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + WSF_ASSERT(pCisCtx); /* At least one CIS in the CIG. */ + + while (pCisCtx) + { + if (pCisCtx->cisCeRef == 0) + { + BbBleData_t * const pBle = &pCisCtx->bleData; + pCisCtx->cisEvtCounter++; + pCisCtx->chIdx = pBle->chan.chanIdx = LmgrSelectNextChannel(&pCisCtx->chanParam, pCisCtx->cisEvtCounter, 0, TRUE); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); + + if (pCisCtx->txTestEnabled) + { + uint32_t sduInt = pCisCtx->sduIntervalMToS; + + while ((pOp->dueUsec - pCisCtx->testSduTs) >= sduInt) + { + lctrCisTxTestPayloadHandler(pCisCtx); + pCisCtx->testSduTs += sduInt; + } + } + + /* Assemble framed data. */ + if ((pCisCtx->framing == LL_ISO_PDU_TYPE_FRAMED) && + pCisCtx->isoalTxCtx.pendQueueSize) + { + uint8_t *pDataBuf = lctrTxIsoDataPduAlloc(); + + if (pDataBuf == NULL) + { + /* TODO optimize statement as the call to WsfMsgFree() has no effect and should not continue to following statement. */ + LL_TRACE_WARN0("LctrTxIso, Unable to allocate PDU for transmit"); + WsfMsgFree(pDataBuf); + } + + lctrIsoHdr_t isoHdr; + + isoHdr.sduLen = lctrAssembleTxFramedPdu(&pCisCtx->isoalTxCtx, pDataBuf, pCisCtx->localDataPdu.maxTxLen); + isoHdr.tsFlag = 0; + + lctrIsoSduTxDecAvailBuf(); + lctrCisTxDataPduQueue(pCisCtx, &isoHdr, pDataBuf); + } + } + else + { + pCisCtx->cisCeRef--; + } + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + if (SchInsertAtDueTime(pOp, NULL)) + { + break; + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + LL_TRACE_WARN1("!!! CIS master schedule conflict eventCounter=%u", pCisCtx->cisEvtCounter); + } + + if (lmgrCb.sendIsoCmplEvt) + { + lctrNotifyHostIsoEventComplete(pCigCtx->cigHandle, (uint32_t) pCisCtx->cisEvtCounter); + } +} + +/*************************************************************************************************/ +/*! + * \brief Abort a connection operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrMstCisCigAbortOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + + /* Need to setup Tx/Rx flush timeout parameter first since some field will be used in the lctrSlvCisInitIsr. */ + + if (pCigCtx->numCisEsted > 0) + { + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + /* It is possible there is no CIS since it is aborting. */ + + while (pCisCtx) + { + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrMstCisInitIsr(pCisCtx); + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + } + + lctrMstCisCigEndOp(pOp); +} + +/*************************************************************************************************/ +/*! + * \brief Complete a transmitted data buffer. + * + * \param pOp Operation context. + * \param status Transmit status. + */ +/*************************************************************************************************/ +void lctrMstCisCigTxCompletion(BbOpDesc_t *pOp, uint8_t status) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + + pCisCtx->txFtParamList.pHead->ftParam.subEvtCounter++; +} + +/*************************************************************************************************/ +/*! + * \brief Complete a received data buffer. + * + * \param pOp Operation context. + * \param pRxBuf Next receive buffer or NULL to flow control. + * \param status Receive status. + */ +/*************************************************************************************************/ +void lctrMstCisCigRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + BbBleData_t * const pBle = &pCisCtx->bleData; + + pCisCtx->txFtParamList.pHead->ftParam.pduAcked = FALSE; + pCisCtx->rxFtParamList.pHead->ftParam.subEvtCounter++; + pCisCtx->rxFtParamList.pHead->ftParam.pduRcved = FALSE; + pCisCtx->validRx = FALSE; + pCisCtx->txPduIsAcked = FALSE; + pCisCtx->pduFlushed = FALSE; + + if (status == BB_STATUS_CRC_FAILED) + { + pCisCtx->isoLinkQualStats.crcErrPkt++; + } + + /*** Cancellation processing ***/ + + if (status == BB_STATUS_CANCELED) + { + lctrCisRxPduFree(pRxBuf); + goto Done; + } + + /*** Receive packet pre-processing ***/ + + if (status == BB_STATUS_SUCCESS) + { + pCisCtx->firstFromPeer = TRUE; + pCisCtx->data.mst.rxFromSlave = TRUE; + } + else if (status == BB_STATUS_CRC_FAILED || + status == BB_STATUS_RX_TIMEOUT || + status == BB_STATUS_FAILED) + { + LL_TRACE_WARN2("lctrMstCisCigRxCompletion: BB failed with status=%u, handle=%u", status, pCisCtx->cisHandle); + LL_TRACE_WARN2("lctrMstCisCigRxCompletion: BB failed with cisEvtCounter=%d, bleChan=%u", pCisCtx->cisEvtCounter, pCisCtx->bleData.chan.chanIdx); + goto PostProcessing; + } + + lctrCisUnpackDataPduHdr(&pCisCtx->rxHdr, pRxBuf); + +#if (LL_ENABLE_TESTER) + if ((llTesterCb.cisAckMode != LL_TESTER_ACK_MODE_NORMAL) || + (llTesterCb.cisFwdPkt == TRUE)) + { + LctrCisProcessRxTxAck(pCisCtx, &pCisCtx->validRx, &pCisCtx->txPduIsAcked); + + /* Don't report the empty packet. */ + if (pCisCtx->rxHdr.len == 0) + { + pCisCtx->validRx = FALSE; + } + } + else +#endif + { + pCisCtx->validRx = lctrCisProcessRxAck(pCisCtx); + pCisCtx->txPduIsAcked = lctrCisProcessTxAck(pCisCtx); + } + + /*** Packet post-processing ***/ + +PostProcessing: + /* Save the Rx buffer and process in the lctrMstCisCigPostSubEvt. */ + pCisCtx->pRxBuf = pRxBuf; + + /* Check rssi value if power monitoring. */ + if (pConnCtx->monitoringState == LCTR_PC_MONITOR_ENABLED) + { + lctrCisPowerMonitorCheckRssi(pOp->prot.pBle->op.mstCis.rssi, + status, + pCisCtx->phySToM + + (((pCisCtx->phySToM == LL_PHY_LE_CODED) && + (pBle->chan.initTxPhyOptions == LL_PHY_OPTIONS_S2_PREFERRED)) ? 1 : 0), + pConnCtx); + } + + /*** ISR complete ***/ + +Done: + lctrCisCheckFtAfterRx(pCisCtx); + + if (status == BB_STATUS_SUCCESS || + status == BB_STATUS_RX_TIMEOUT || + status == BB_STATUS_CRC_FAILED || + status == BB_STATUS_FAILED) + { + + lctrCisProcessTxAckCleanup(pCisCtx); + lctrCisRxPostProcessing(pCisCtx, pCisCtx->pRxBuf); + } + + return; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_slave.c new file mode 100644 index 00000000000..269c90468b1 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_cis_slave.c @@ -0,0 +1,1295 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller slave connected isochronous stream ISR callbacks. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int.h" +#include "lctr_int_cis.h" +#include "lctr_int_cis_slave.h" +#include "lctr_int_iso.h" +#include "lmgr_api_conn.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "bb_ble_api.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include +#include "pal_codec.h" + +#if (LL_ENABLE_TESTER) +#include "pal_bb_ble_tester.h" +#endif + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +#if (LL_ENABLE_TESTER) +void LctrCisProcessRxTxAck(lctrCisCtx_t *pCtx, bool_t *pValidRx, bool_t *pTxPduIsAcked); +#endif + +/*************************************************************************************************/ +/*! + * \brief Initialize slave CIS ISR resources. + * + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +static void lctrSlvCisInitIsr(lctrCisCtx_t *pCisCtx) +{ + pCisCtx->data.slv.syncWithMaster = FALSE; + pCisCtx->data.slv.rxFromMaster = FALSE; + pCisCtx->data.slv.firstRxFromMaster = TRUE; + pCisCtx->data.slv.rxStatus = BB_STATUS_RX_TIMEOUT; + pCisCtx->subEvtCounter = 0; + pCisCtx->txDataCounter = 0; + pCisCtx->rxDataCounter = 0; + + pCisCtx->txFtParamList.pHead->ftParam.subEvtCounter = 0; + pCisCtx->rxFtParamList.pHead->ftParam.subEvtCounter = 0; + + if (pCisCtx->txFtParamList.pHead->ftParam.bn == 0) + { + pCisCtx->isTxDone = TRUE; + } + else + { + pCisCtx->isTxDone = FALSE; + } + + /*** Setup for transmit ***/ + + pCisCtx->txHdr.cie = 0; + pCisCtx->txHdr.np = 0; + + /*** Setup for receive ***/ + + pCisCtx->rxHdr.cie = 0; + pCisCtx->rxHdr.np = 0; + pCisCtx->rxHdr.len = 0; + pCisCtx->rxHdr.llid = LL_LLID_ISO_UNF_END_PDU; +} + +/*************************************************************************************************/ +/*! + * \brief Execution CIG operation + * + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +static void lctrSlvCisCigExecOp(lctrCisCtx_t *pCisCtx) +{ + uint8_t *pBuf; + + if (!lmgrIsoCb.availRxBuf) + { + LL_TRACE_ERR1("!!! lctrSlvCisCigExecOp, RX buffer not available, cisHandle=%u", pCisCtx->cisHandle); + return; /* flow control Rx */ + } + + /*** Setup receiver ***/ + + if ((pBuf = lctrCisRxPduAlloc(pCisCtx->localDataPdu.maxRxLen)) != NULL) + { +#if (LL_ENABLE_TESTER) + if (llTesterCb.isoAccAddrSeTrigMask && + (llTesterCb.isoAccAddrSeTrigMask & (1 << pCisCtx->subEvtCounter)) && + llTesterCb.isoAccAddrInvForRx) + { + PalBbTesterInvalidateNextAccAddr(TRUE); + + if (llTesterCb.isoAccAddrInvNumTrig) + { + llTesterCb.isoAccAddrInvNumTrig--; + if (llTesterCb.isoAccAddrInvNumTrig == 0) + { + llTesterCb.isoAccAddrSeTrigMask = 0; + } + } + } +#endif + + BbBleCisRxData(pBuf, LCTR_CIS_DATA_PDU_LEN(pCisCtx->localDataPdu.maxRxLen)); + /* Rx may fail; no more important statements in this code path */ + } + else + { + LL_TRACE_ERR1("!!! OOM while initializing receive buffer at start of CIS, cisHandle=%u", pCisCtx->cisHandle); + BbSetBodTerminateFlag(); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check Tx flush timeout and flush PDU if necessary after RX. + * +* \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckTxFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->txHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParam_t *pFtParam = &pCisCtx->txFtParamList.pHead->ftParam; + + if (pFtParam->pduAcked) + { + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + lctrCisIncPacketCounterTx(pCisCtx); + pFtParam->pduCounter++; + } + else + { + /* Check if this is the last FT interval. */ + if ((pFtParam->intervalCounter + 1) == pFtParam->intervalTotal) + { + if (pFtParam->subEvtCounter == pFtParam->lastSubEvtFt[pFtParam->pduCounter]) + { + /* PDU needs to be flushed. */ + pCisCtx->txHdr.sn++; + + lctrCisIncPacketCounterTx(pCisCtx); + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + + if (pFtParam->pduType[pFtParam->pduCounter] == LCTR_CIS_PDU_NON_EMPTY) + { + /* Need to remove from ack queue if non-empty PDU. */ + lctrCisTxPduAck(pCisCtx); + pCisCtx->pduFlushed = TRUE; /* Set the flag, lctrCisProcessTxAckCleanup will be called to do the cleanup later in the lctrMstCisCigPostSubEvt. */ + } + pFtParam->pduCounter++; + pCisCtx->isoLinkQualStats.txUnAckPkt++; + } + } + else /* Implies that a retransmit will happen. */ + { + pCisCtx->isoLinkQualStats.retransmitPkt++; + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->txFtParamList); + } + + /* No more data to send, send NULL packet. */ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + pCisCtx->isTxDone = TRUE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check Rx flush timeout and flush PDU if necessary after RX. + * +* \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckRxFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->rxFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->rxHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParam_t *pFtParam = &pCisCtx->rxFtParamList.pHead->ftParam; + + if (pFtParam->pduRcved) + { + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + pFtParam->pduCounter++; + } + else + { + /* Check if this is the last interval before FT. */ + if ((pFtParam->intervalCounter + 1) == pFtParam->intervalTotal) + { + if (pFtParam->subEvtCounter == pFtParam->lastSubEvtFt[pFtParam->pduCounter]) + { + /* PDU needs to be flushed. */ + pCisCtx->txHdr.nesn++; + lctrCisIncPacketCounterRx(pCisCtx); + pFtParam->isPduDone[pFtParam->pduCounter] = TRUE; /* The PDU is done. */ + pFtParam->pduCounter++; + pCisCtx->isoLinkQualStats.rxUnreceivedPkt++; + pCisCtx->isoalRxCtx.pduFlushed = TRUE; + pCisCtx->isoalRxCtx.packetSequence++; + pCisCtx->numRxMissed++; + } + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->rxFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckTxFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->txFtParamList)) + { + /* List is empty. */ + return; + } + + if (pCisCtx->txHdr.np) + { + /* NULL PDU doesn't need to be acked or flushed. */ + return; + } + + lctrFtParamNode_t *pNode = pCisCtx->txFtParamList.pHead; + + /* Increment interval counter for all the node in the list. */ + while (pNode) + { + pNode->ftParam.intervalCounter++; + pNode = pNode->pNext; + } + + /* Only check the head node */ + lctrFtParam_t *pFtParam = &pCisCtx->txFtParamList.pHead->ftParam; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE && /* If the PDU is not done. */ + pFtParam->intervalCounter == pFtParam->intervalTotal) /* Check if the PDU needs to be flush in this interval. */ + { + pFtParam->isPduDone[i] = TRUE; + pCisCtx->txHdr.sn++; + + PalBbBleTxBufDesc_t bbDesc[3]; + if (lctrCisTxQueuePeek(pCisCtx, &bbDesc[0])) + { + /* Need to remove from ack queue if non-empty PDU. */ + lctrCisTxPduAck(pCisCtx); + lctrCisTxQueuePopCleanup(pCisCtx); + } + pFtParam->pduCounter++; + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + /* pCisCtx->isTxDone = TRUE; No need since BOD is done. */ + lctrCisFtRemoveHead(&pCisCtx->txFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +static void lctrCisCheckRxFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + if (lctrCisFtIsListEmpty(&pCisCtx->rxFtParamList)) + { + /* List is empty. */ + return; + } + + lctrFtParamNode_t *pNode = pCisCtx->rxFtParamList.pHead; + + /* Increment interval counter for all the node in the list. */ + while (pNode) + { + pNode->ftParam.intervalCounter++; + pNode = pNode->pNext; + } + + /* Only check the head node */ + lctrFtParam_t *pFtParam = &pCisCtx->rxFtParamList.pHead->ftParam; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE && /* If the PDU is not done. */ + pFtParam->intervalCounter == pFtParam->intervalTotal) /* Check if the PDU needs to be flush in this interval. */ + { + pFtParam->isPduDone[i] = TRUE; + pCisCtx->txHdr.nesn++; + lctrCisIncPacketCounterRx(pCisCtx); + pFtParam->pduCounter++; + } + } + + /* Remove the node if all the items are done. */ + bool_t removeFromList = TRUE; + for (unsigned int i = 0; i < WSF_MIN(pFtParam->bn, LCTR_MAX_BN); i++) + { + if (pFtParam->isPduDone[i] == FALSE) + { + removeFromList = FALSE; + break; + } + } + if (removeFromList == TRUE) + { + lctrCisFtRemoveHead(&pCisCtx->rxFtParamList); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after RX. + * +* \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckFtAfterRx(lctrCisCtx_t *pCisCtx) +{ + lctrCisCheckTxFtAfterRx(pCisCtx); + lctrCisCheckRxFtAfterRx(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Check flush timeout and flush PDU if necessary after end of BOD. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrCisCheckFtAfterBod(lctrCisCtx_t *pCisCtx) +{ + lctrCisCheckTxFtAfterBod(pCisCtx); + lctrCisCheckRxFtAfterBod(pCisCtx); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Setup for the next current operation. + * + * \param pOp Begin operation. + * \param pNewCisCtx New CIS context to begin. + * + * \return Offset in usec. + */ +/*************************************************************************************************/ +uint32_t lctrSlvCisCheckContOp(BbOpDesc_t *pOp, bool_t *pNewCisCtx) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + uint32_t wwTotalUsec; + uint32_t offsetUsec; + uint32_t delayUsec = pCisCtx->delayUsec; + bool_t isSuccess = (pCisCtx->data.slv.rxStatus == BB_STATUS_SUCCESS ? TRUE : FALSE); + + WSF_ASSERT(pCisCtx); + + BbBleData_t *pBle = &pCisCtx->bleData; + BbBleSlvCisEvent_t * const pCis = &pBle->op.slvCis; + + if (pCigCtx->packing == LL_PACKING_SEQUENTIAL) + { + uint32_t subIntervUsec = pCisCtx->subIntervUsec; + + pCisCtx->subEvtCounter++; + + if (pCisCtx->rxHdr.cie || pCisCtx->txHdr.cie) + { + goto SwitchSeq; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + goto SwitchSeq; + } + + if (pCisCtx->subEvtCounter == pCisCtx->nse) + { + pCisCtx->txHdr.cie = 1; + /* There is no more subevent. */ + goto SwitchSeq; + } + + /*** Continue current CIS ***/ + + /* Set next channel index. */ + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + + /* Only apply WW when rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(subIntervUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = subIntervUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = subIntervUsec; + } + return offsetUsec; + +SwitchSeq: + /* Skip additional sub-events if switching CIS, might not be used if next CIS is NULL */ + subIntervUsec = pCisCtx->nextCisOffsetUsec - subIntervUsec * (pCisCtx->subEvtCounter - 1); /* pCisCtx->subEvtCounter is already incremented */ + + if ((pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx)) == NULL) + { + goto Done; + } + else + { + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + goto Done; + } + + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrSlvCisInitIsr(pCisCtx); + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Continue on the next subevent. */ + pBle->op.slvCis.rxTsUsec = pCis->rxTsUsec; + + /* Move the current CIS to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + + /* Only apply WW when rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(subIntervUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = subIntervUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = subIntervUsec; + } + + return offsetUsec; + } + } + else + { + uint32_t subIntervUsec = pCisCtx->subIntervUsec; + uint8_t oriNextSubEvtChanIdx = pCisCtx->nextSubEvtChanIdx; + + if (pCisCtx->rxHdr.cie || pCisCtx->txHdr.cie) + { + pCisCtx->cisDone = TRUE; + goto SwitchInt; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + lctrCisSetCisDone(&pCigCtx->list, pCisCtx); + goto SwitchInt; + } + + pCisCtx->subEvtCounter++; + + if (pCisCtx->subEvtCounter == pCisCtx->nse) + { + pCisCtx->txHdr.cie = 1; + pCisCtx->cisDone = TRUE; + /* There is no more subevent. */ + goto SwitchInt; + } + +SwitchInt: + if (lctrCisGetListCount(&pCigCtx->list) == 1) + { + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /*** Continue current CIS ***/ + + /* Set next channel index. */ + pBle->chan.chanIdx = oriNextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + /* Only apply WW when rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(subIntervUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = subIntervUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = subIntervUsec; + } + + return offsetUsec; + } + + if ((pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx)) == NULL) + { + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /* End of the list, loop back to the head of the CIS. */ + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->isLoopBack = TRUE; + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Point to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + + /* Only apply WW when rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(delayUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = delayUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = delayUsec; + } + + return offsetUsec; + } + else + { + /* Get the next CIS in the list. */ + if (lctrCisAreCisCtxDone(&pCigCtx->list)) + { + goto Done; + } + + /* Check whether the CIS shall start or not. */ + if (pCisCtx->cisCeRef != 0) + { + /*** Continue head CIS ***/ + + lctrCisSetCisDone(&pCigCtx->list, pCisCtx); + + lctrCisCtx_t *pNextCtx, *pTempCtx; + uint32_t addDelayUsec = 0; + + pTempCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->pCisCtx = pTempCtx; + pBle = &pTempCtx->bleData; + memcpy(&pBle->chan, &pTempCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pTempCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + pOp->prot.pBle = pBle; + pCigCtx->isLoopBack = TRUE; + + while (pTempCtx) + { + pNextCtx = lctrCisGetNextCis(&pCigCtx->list, pTempCtx); + + if (pNextCtx == NULL) + { + break; + } + + if (pNextCtx == pCisCtx) + { + break; + } + + addDelayUsec += pTempCtx->delayUsec; + pTempCtx = pNextCtx; + } + + /* Only apply WW when Rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(subIntervUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = subIntervUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = subIntervUsec; + } + + return (offsetUsec - addDelayUsec); + } + + if (pCigCtx->isLoopBack == FALSE) + { + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrSlvCisInitIsr(pCisCtx); + } + + pBle = &pCisCtx->bleData; + *pNewCisCtx = TRUE; + + /* Point to the next CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + if (pCigCtx->isLoopBack == FALSE) + { + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + } + else + { + pBle->chan.chanIdx = pCisCtx->nextSubEvtChanIdx; /* Next subevent channel index is pre-calculated. */ + } + + /* Only apply WW when rx success. */ + if (isSuccess) + { + wwTotalUsec = lctrCalcWindowWideningUsec(delayUsec, pCigCtx->roleData.slv.totalAcc); + offsetUsec = delayUsec - wwTotalUsec; + pCis->rxSyncDelayUsec = (wwTotalUsec << 1); + } + else + { + offsetUsec = delayUsec; + } + return offsetUsec; + } + } + +Done: + /* All CISs are done. Set next CIS to the head of the list. */ + pCigCtx->pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pOp->prot.pBle = &pCigCtx->pCisCtx->bleData; + *pNewCisCtx = TRUE; + lctrCisClearCisDone(&pCigCtx->list); + return 0; +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup a connection operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrSlvCisCigCleanupOp(BbOpDesc_t *pOp) +{ + +} + +/*************************************************************************************************/ +/*! + * \brief End a connection operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrSlvCisCigEndOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + WSF_ASSERT(pCisCtx); /* At least one CIS in the CIG. */ + + if (pCisCtx->data.slv.syncWithMaster) + { + /* Re-sync to master's clock. */ + pCigCtx->roleData.slv.anchorPointUsec = pCisCtx->data.slv.firstRxStartTsUsec; + pCigCtx->roleData.slv.lastActiveEvent = pCigCtx->roleData.slv.cigEvtCounter; + } + + while (pCisCtx) + { + /* LL_CIS_TERMINATION case */ + if ((pCisCtx->isClosing == TRUE) || + (pConnCtx->enabled == FALSE) || + (lctrResetEnabled == TRUE)) + { + /* This variable set to TRUE means it is a CIS disconnect that requires an event generation. */ + if (pCisCtx->isClosing == TRUE) + { + /* This was a host-initiated termination of the CIS. */ + lctrNotifyHostCisTerm(pCisCtx); + } + + pCigCtx->numCisEsted--; + pCisCtx->isClosing = FALSE; + lctrCleanupCtx(pCisCtx); + } + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + if (pCigCtx->numCisEsted == 0) + { + return; + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + + while (pCisCtx) + { + lctrCisCheckFtAfterBod(pCisCtx); + + if (!pCisCtx->connEst && pCisCtx->data.slv.rxFromMaster) + { + WsfTimerStartMs(&pCisCtx->tmrSupTimeout, pCisCtx->supTimeoutMs); + pCisCtx->connEst = TRUE; + + if (pCisCtx->powerIndReq && lctrSendPowerChangeIndCback) + { + uint8_t txPhy = (pCisCtx->role == LL_ROLE_MASTER) ? pCisCtx->phyMToS : pCisCtx->phySToM; + lctrSendPowerChangeIndCback(pConnCtx, txPhy, 0, pLctrRtCfg->defTxPwrLvl, TRUE); + } + + lctrNotifyHostCisEst(pCisCtx, LL_SUCCESS, pCisCtx->cigSyncDelayUsec); + } + else if (pCisCtx->data.slv.rxFromMaster) + { + /* Reset supervision timer. */ + WsfTimerStartMs(&pCisCtx->tmrSupTimeout, pCisCtx->supTimeoutMs); + } + + /* Failed to receive packet within the first 6 intervals. */ + if ((pCisCtx->firstFromPeer == FALSE) && (pCisCtx->cisEvtCounter == LCTR_FAST_TERM_CNT)) + { + LL_TRACE_WARN0("CIS terminated due to fast termination timeout"); + lctrCisStoreConnFailEstablishTerminateReason(pCisCtx); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); + + if (pCigCtx->numCisEsted == 1) + { + /* If the last CIS to close, schedule no more operation. */ + return; + } + } + + /* Terminate connection */ + if (lctrCheckForCisLinkTerm(pCisCtx->aclHandle)) + { + lctrSendCisLlcpMsg(pCisCtx, LCTR_CIS_TERM_EVENT_CIS_TERM); + } + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + + if (pCigCtx->headCisRmved == TRUE) + { + BbBleData_t *pBle = &pCisCtx->bleData; + /* Move the current CIS to the head CIS. */ + pOp->prot.pBle = pBle; + pCigCtx->pCisCtx = pCisCtx; + memcpy(&pBle->chan, &pCigCtx->pCisCtx->bleData.chan, sizeof(pBle->chan)); + pBle->chan.chanIdx = pCigCtx->pCisCtx->chIdx; /* Set the next channel to the first channel in the next CIS. */ + } + + uint16_t numUnsyncIntervals = pCigCtx->roleData.slv.cigEvtCounter - pCigCtx->roleData.slv.lastActiveEvent; + + /* Update txPower. */ + pCisCtx->bleData.chan.txPower = LCTR_GET_TXPOWER(pConnCtx, pCisCtx->phySToM, pCisCtx->bleData.chan.initTxPhyOptions); +#if(LL_ENABLE_TESTER) + pCisCtx->bleData.chan.txPower += pConnCtx->bleData.chan.txPwrOffset; +#endif + + while (TRUE) + { + pCigCtx->roleData.slv.cigEvtCounter++; + numUnsyncIntervals += 1; + + uint32_t cigInterUsec = LCTR_ISO_INT_TO_US(pCigCtx->isoInterval); + uint32_t unsyncTimeUsec = cigInterUsec * numUnsyncIntervals; + uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pCigCtx->roleData.slv.totalAcc); + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + WSF_ASSERT(pCisCtx); /* At least one CIS in the CIG. */ + + while (pCisCtx) + { + if (pCisCtx->cisCeRef == 0) + { + BbBleData_t * const pBle = &pCisCtx->bleData; + pCisCtx->cisEvtCounter++; + pCisCtx->chIdx = pBle->chan.chanIdx = LmgrSelectNextChannel(&pCisCtx->chanParam, pCisCtx->cisEvtCounter, 0, TRUE); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); + + if (pCisCtx->txTestEnabled) + { + uint32_t sduInt = pCisCtx->sduIntervalSToM; + + while ((pOp->dueUsec - pCisCtx->testSduTs) >= sduInt) + { + lctrCisTxTestPayloadHandler(pCisCtx); + pCisCtx->testSduTs += sduInt; + } + } + + /* Assemble framed data. */ + if ((pCisCtx->framing == LL_ISO_PDU_TYPE_FRAMED) && + pCisCtx->isoalTxCtx.pendQueueSize) + { + uint8_t *pDataBuf = lctrTxIsoDataPduAlloc(); + + if (pDataBuf == NULL) + { + /* TODO optimize statement as the call to WsfMsgFree() has no effect and should not continue to following statement. */ + LL_TRACE_WARN0("LctrTxIso, Unable to allocate PDU for transmit"); + WsfMsgFree(pDataBuf); + } + + lctrIsoHdr_t isoHdr; + + isoHdr.sduLen = lctrAssembleTxFramedPdu(&pCisCtx->isoalTxCtx, pDataBuf, pCisCtx->localDataPdu.maxTxLen); + isoHdr.tsFlag = 0; + + lctrIsoSduTxDecAvailBuf(); + lctrCisTxDataPduQueue(pCisCtx, &isoHdr, pDataBuf); + } + + /* TODO: resolve magic number */ + if (pCisCtx->nse < 3) + { + if (wwTotalUsec >= ((cigInterUsec >> 1) - WSF_MAX(LL_BLE_TIFS_US, BbGetSchSetupDelayUs()))) + { + LL_TRACE_WARN2("!!! Terminating CIG due to excessive WW handle=%u, eventCounter=%u", pCisCtx->cisHandle, pCisCtx->cisEvtCounter); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); + + if (pCigCtx->numCisEsted == 1) + { + /* If the last CIS to close, schedule no more operation. */ + return; + } + } + } + else + { + if (wwTotalUsec >= pCisCtx->subIntervUsec) + { + LL_TRACE_WARN2("!!! Terminating CIG due to excessive WW handle=%u, eventCounter=%u", pCisCtx->cisHandle, pCisCtx->cisEvtCounter); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); + + if (pCigCtx->numCisEsted == 1) + { + /* If the last CIS to close, schedule no more operation. */ + return; + } + } + } + } + else + { + pCisCtx->cisCeRef--; + } + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + + /* Advance to next interval. */ + pOp->dueUsec = pCigCtx->roleData.slv.anchorPointUsec + unsyncTimeUsec - wwTotalUsec; + + pOp->minDurUsec = pCigCtx->cigSyncDelayUsec + wwTotalUsec; + pCigCtx->pCisCtx->bleData.op.slvCis.rxSyncDelayUsec = (wwTotalUsec << 1); + + if (pCigCtx->headCisRmved == TRUE) + { + pCigCtx->headCisRmved = FALSE; + pOp->dueUsec += pCigCtx->offsetUsec; + pCigCtx->offsetUsec = 0; + } + + if (SchInsertAtDueTime(pOp, lctrCisResolveConflict)) + { + break; + } + + pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + LL_TRACE_WARN1("!!! CIG slave schedule conflict eventCounter=%u", pCisCtx->cisEvtCounter); + } + + + if (lmgrCb.sendIsoCmplEvt) + { + lctrNotifyHostIsoEventComplete(pCigCtx->cigHandle, (uint32_t) pCisCtx->cisEvtCounter); + } +} + +/*************************************************************************************************/ +/*! + * \brief Abort a connection operation. + * + * \param pOp Completed operation. + */ +/*************************************************************************************************/ +void lctrSlvCisCigAbortOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + + if (pCigCtx->numCisEsted > 0) + { + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + /* It is possible there is no CIS since it is aborting. */ + + while (pCisCtx) + { + lctrFtParam_t txFtParam, rxFtParam; + + /* Need to setup Tx/Rx flush timeout parameter first since some field will be used in the lctrSlvCisInitIsr. */ + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrSlvCisInitIsr(pCisCtx); + + pCisCtx = lctrCisGetNextCis(&pCigCtx->list, pCisCtx); + } + } + + lctrSlvCisCigEndOp(pOp); +} + +/*************************************************************************************************/ +/*! + * \brief Complete a transmitted data buffer. + * + * \param pOp Operation context. + * \param status Transmit status. + */ +/*************************************************************************************************/ +void lctrSlvCisCigTxCompletion(BbOpDesc_t *pOp, uint8_t status) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + + pCisCtx->txFtParamList.pHead->ftParam.subEvtCounter++; +} + +/*************************************************************************************************/ +/*! + * \brief Complete a received data buffer. + * + * \param pOp Operation context. + * \param pRxBuf Next receive buffer or NULL to flow control. + * \param status Receive status. + */ +/*************************************************************************************************/ +void lctrSlvCisCigRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx = pCigCtx->pCisCtx; + lctrConnCtx_t * pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + BbBleData_t * const pBle = &pCisCtx->bleData; + BbBleSlvCisEvent_t * const pCis = &pBle->op.slvCis; + + pCisCtx->data.slv.rxStatus = status; + + pCisCtx->rxFtParamList.pHead->ftParam.subEvtCounter++; + pCisCtx->txFtParamList.pHead->ftParam.pduAcked = FALSE; + pCisCtx->rxFtParamList.pHead->ftParam.pduRcved = FALSE; + pCisCtx->validRx = FALSE; + pCisCtx->txPduIsAcked = FALSE; + pCisCtx->pduFlushed = FALSE; + + /*** Cancellation processing ***/ + + if (status == BB_STATUS_CANCELED) + { + lctrCisRxPduFree(pRxBuf); + + goto Done; + } + + /*** CIS event pre-processing ***/ + + /* Save time stamp for the first Rx. */ + if (pCisCtx->data.slv.firstRxFromMaster == TRUE) + { + pCisCtx->data.slv.firstRxFromMaster = FALSE; + pCisCtx->data.slv.firstRxStartTsUsec = pCis->startTsUsec; + } + + if ((!pCisCtx->data.slv.syncWithMaster) && + (status == BB_STATUS_SUCCESS)) + { + /* Receive successful packet, update anchor point later. */ + pCisCtx->firstFromPeer = TRUE; + pCisCtx->data.slv.syncWithMaster = TRUE; + } + + /*** Receive packet pre-processing ***/ + + switch (status) + { + case BB_STATUS_SUCCESS: + pCisCtx->data.slv.rxFromMaster = TRUE; + pCisCtx->data.slv.consCrcFailed = 0; + break; + case BB_STATUS_CRC_FAILED: + pCisCtx->isoLinkQualStats.crcErrPkt++; + /* Fallthrough */ + case BB_STATUS_FAILED: + case BB_STATUS_RX_TIMEOUT: + LL_TRACE_WARN2("lctrSlvCisCigRxCompletion: BB failed with status=%u, handle=%u", status, pCisCtx->cisHandle); + LL_TRACE_WARN2("lctrSlvCisCigRxCompletion: BB failed with cisEvtCounter=%d, bleChan=%u", pCisCtx->cisEvtCounter, pCisCtx->bleData.chan.chanIdx); + + pCisCtx->validRx = FALSE; + pCisCtx->txPduIsAcked = FALSE; + + goto SetupTx; + + default: + break; + } + + lctrCisUnpackDataPduHdr(&pCisCtx->rxHdr, pRxBuf); + +#if (LL_ENABLE_TESTER) + if ((llTesterCb.cisAckMode != LL_TESTER_ACK_MODE_NORMAL) || + (llTesterCb.cisFwdPkt == TRUE)) + { + LctrCisProcessRxTxAck(pCisCtx, &pCisCtx->validRx, &pCisCtx->txPduIsAcked); + + /* Don't report the empty packet. */ + if (pCisCtx->rxHdr.len == 0) + { + pCisCtx->validRx = FALSE; + } + } + else +#endif + { + pCisCtx->validRx = lctrCisProcessRxAck(pCisCtx); + pCisCtx->txPduIsAcked = lctrCisProcessTxAck(pCisCtx); /* Always Tx after Rx. */ + } + + /*** Setup for transmit ***/ + +SetupTx: + + lctrCisCheckFtAfterRx(pCisCtx); + + /* Slave always transmits after receiving. */ + lctrCisSetupForTx(pCigCtx, status, TRUE); + + /* Tx post-processing. */ + lctrCisProcessTxAckCleanup(pCisCtx); + + /* Rx post-processing. */ + lctrCisRxPostProcessing(pCisCtx, pRxBuf); + + /* Check rssi value if power monitoring. */ + if (pConnCtx->monitoringState == LCTR_PC_MONITOR_ENABLED) + { + lctrCisPowerMonitorCheckRssi(pOp->prot.pBle->op.slvCis.rssi, + status, + pCisCtx->phySToM + + (((pCisCtx->phySToM == LL_PHY_LE_CODED) && + (pBle->chan.initTxPhyOptions == LL_PHY_OPTIONS_S2_PREFERRED)) ? 1 : 0), + pConnCtx); + } + + return; + + /*** ISR complete ***/ + +Done: + lctrCisCheckFtAfterRx(pCisCtx); + + /* Tx post-processing. */ + lctrCisProcessTxAckCleanup(pCisCtx); + + return; +} + +/*************************************************************************************************/ +/*! + * \brief Begin a connection operation. + * + * \param pOp Begin operation. + * + * \note Scheduler may call this routine multiple times in the following situation: + * this BOD is pending and a BOD is inserted before. + */ +/*************************************************************************************************/ +void lctrSlvCisCigBeginOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + pCisCtx = pCigCtx->pCisCtx; + pCigCtx->isLoopBack = FALSE; + + /* Need to setup Tx/Rx flush timeout parameter first since some field will be used in the lctrSlvCisInitIsr. */ + lctrFtParam_t txFtParam, rxFtParam; + + if (pCisCtx->bnSToM) + { + lctrCisInitFtParam(&txFtParam, pCisCtx->bnSToM, pCisCtx->ftSToM, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->txFtParamList, &txFtParam); /* Assume there is memory. */ + } + + if (pCisCtx->bnMToS) + { + lctrCisInitFtParam(&rxFtParam, pCisCtx->bnMToS, pCisCtx->ftMToS, pCisCtx->nse); + (void)lctrCisFtInsertTail(&pCisCtx->rxFtParamList, &rxFtParam); /* Assume there is memory. */ + } + + lctrSlvCisInitIsr(pCisCtx); + + lctrSlvCisCigExecOp(pCisCtx); +} + +/************************************************* ************************************************/ +/*! + * \brief Begin a connection operation. + * + * \param pOp Begin operation. + * + * \note Scheduler may call this routine multiple times in the following situation: + * this BOD is pending and a BOD is inserted before. + */ +/*************************************************************************************************/ +void lctrSlvCisCigContOp(BbOpDesc_t *pOp) +{ + lctrCigCtx_t * const pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + pCisCtx = pCigCtx->pCisCtx; + + lctrSlvCisCigExecOp(pCisCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Post subevent callback, setup for the next subevent channel index. + * + * \param pOp Current operation. + * \param status Status. + */ +/*************************************************************************************************/ +void lctrSlvCisCigPostSubEvt(BbOpDesc_t *pOp, uint8_t status) +{ + lctrCigCtx_t *pCigCtx = pOp->pCtx; + lctrCisCtx_t *pCisCtx; + + WSF_ASSERT(pCigCtx); + pCisCtx = pCigCtx->pCisCtx; + + WSF_ASSERT(pCisCtx); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn.c index 3868d3d9bc4..9493c0d377f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave connection ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave connection ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -50,8 +51,6 @@ static union * \brief Setup next transmit data buffer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrBuildEmptyPdu(lctrConnCtx_t *pCtx) @@ -71,8 +70,6 @@ static inline void lctrBuildEmptyPdu(lctrConnCtx_t *pCtx) * * \param pHdr Unpacked PDU header. * \param pBuf Packed packet buffer. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrUpdateFlowCtrlBits(const lctrDataPduHdr_t *pHdr, uint8_t *pBuf) @@ -182,8 +179,6 @@ uint8_t *lctrProcessRxAck(lctrConnCtx_t *pCtx) * \brief Last Data PDU acknowledged by peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrTxPduAck(lctrConnCtx_t *pCtx) @@ -240,8 +235,6 @@ bool_t lctrProcessTxAck(lctrConnCtx_t *pCtx) * * \param pCtx Connection context. * - * \return None. - * * Cleanup from Tx acknowledgment processing. */ /*************************************************************************************************/ @@ -383,13 +376,13 @@ void lctrRxPostProcessing(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t *pNextRx * \brief Check for maximum CE duration. * * \param pCtx Connection context. - * \param ceStart CE start time. + * \param ceStartUsec CE start time in microseconds. * \param pendDurUsec Pending operation duration in microseconds. * * \return FALSE if within duration period, TRUE if exceeds period. */ /*************************************************************************************************/ -bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDurUsec) +bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStartUsec, uint32_t pendDurUsec) { BbOpDesc_t *pOp = &pCtx->connBod; @@ -398,7 +391,7 @@ bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDu return FALSE; } - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); + const uint32_t curTime = PalBbGetCurrentTime(); const uint32_t setupDelayUsec = BbGetSchSetupDelayUs(); uint32_t availCeUsec = LCTR_CONN_IND_US(pCtx->connInterval); @@ -406,10 +399,10 @@ bool_t lctrExceededMaxDur(lctrConnCtx_t *pCtx, uint32_t ceStart, uint32_t pendDu if (pOp->pNext) { /* Limit CE duration to the edge of neighboring BOD. */ - availCeUsec = WSF_MIN(availCeUsec, BB_TICKS_TO_US(pOp->pNext->due - ceStart)); + availCeUsec = WSF_MIN(availCeUsec, BbGetTargetTimeDelta(pOp->pNext->dueUsec, ceStartUsec)); } - if ((BB_TICKS_TO_US(curTime - ceStart) + LL_BLE_TIFS_US + pendDurUsec + setupDelayUsec) > availCeUsec) + if ((BbGetTargetTimeDelta(curTime, ceStartUsec) + LL_BLE_TIFS_US + pendDurUsec + setupDelayUsec) > availCeUsec) { return TRUE; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_master.c index 91d127316a5..d6ef7af5396 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -65,8 +66,6 @@ extern void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **p * \brief Update a connection operation. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstConnUpdateOp(lctrConnCtx_t *pCtx) @@ -89,9 +88,7 @@ static void lctrMstConnUpdateOp(lctrConnCtx_t *pCtx) /*** General setup ***/ - const uint32_t txWinOffset = BB_BLE_TO_BB_TICKS(LCTR_CONN_IND_TICKS(pConnUpdInd->txWinOffset)); - - pOp->due += txWinOffset; + pOp->dueUsec += BB_BLE_TO_US(LCTR_CONN_IND_TICKS(pConnUpdInd->txWinOffset)); pOp->maxDurUsec = LCTR_CONN_IND_US(pCtx->connInterval); /* Unconditionally reset supervision timer with transitional value. @@ -120,8 +117,6 @@ static void lctrMstConnUpdateOp(lctrConnCtx_t *pCtx) * \brief Update the channel map. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstChanMapUpdateOp(lctrConnCtx_t *pCtx) @@ -132,6 +127,12 @@ static void lctrMstChanMapUpdateOp(lctrConnCtx_t *pCtx) /* Delay notification until CE starts. */ pCtx->llcpInstantComp = TRUE; + /* Update the channel map for CIS master as well. */ + if (LctrUpdateCisChanMapFn) + { + LctrUpdateCisChanMapFn(LCTR_GET_CONN_HANDLE(pCtx)); + } + LL_TRACE_INFO2(" >>> Channel map updated, handle=%u, eventCounter=%u <<<", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); } @@ -140,26 +141,41 @@ static void lctrMstChanMapUpdateOp(lctrConnCtx_t *pCtx) * \brief Update the selected PHY. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstPhyUpdateOp(lctrConnCtx_t *pCtx) { - uint8_t txPhyOld = lctrPhyToPhysBit(pCtx->bleData.chan.txPhy); - uint8_t rxPhyOld = lctrPhyToPhysBit(pCtx->bleData.chan.rxPhy); + BbBleData_t * pBle = &pCtx->bleData; + uint8_t txPhyOld = lctrPhyToPhysBit(pBle->chan.txPhy); + uint8_t rxPhyOld = lctrPhyToPhysBit(pBle->chan.rxPhy); /* Notify host only if PHY changed. */ if ((pCtx->phyUpd.masterToSlavePhy != LL_PHYS_NONE) && (pCtx->phyUpd.masterToSlavePhy != txPhyOld)) { - pCtx->bleData.chan.txPhy = lctrPhysBitToPhy(pCtx->phyUpd.masterToSlavePhy); + pBle->chan.txPhy = lctrPhysBitToPhy(pCtx->phyUpd.masterToSlavePhy); + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, pCtx->bleData.chan.txPhy, pBle->chan.initTxPhyOptions); pCtx->llcpNotifyMask |= 1 << LCTR_PROC_PHY_UPD; + + if (pBle->chan.txPower == LL_PWR_CTRL_TXPOWER_UNMANAGED) + { + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + LCTR_SET_TXPOWER(pCtx, pBle->chan.txPhy, pLctrRtCfg->defTxPwrLvl); + if (pBle->chan.txPhy == BB_PHY_BLE_CODED) + { + LCTR_SET_TXPOWER(pCtx, LL_PC_PHY_CODED_S2, pLctrRtCfg->defTxPwrLvl); + } + + if ((pCtx->usedFeatSet & LL_FEAT_POWER_CHANGE_IND) && lctrSendPowerChangeIndCback) + { + lctrSendPowerChangeIndCback(pCtx, pBle->chan.txPhy, 0, pLctrRtCfg->defTxPwrLvl, TRUE); + } + } } if ((pCtx->phyUpd.slaveToMasterPhy != LL_PHYS_NONE) && (pCtx->phyUpd.slaveToMasterPhy != rxPhyOld)) { - pCtx->bleData.chan.rxPhy = lctrPhysBitToPhy(pCtx->phyUpd.slaveToMasterPhy); + pBle->chan.rxPhy = lctrPhysBitToPhy(pCtx->phyUpd.slaveToMasterPhy); pCtx->llcpNotifyMask |= 1 << LCTR_PROC_PHY_UPD; } @@ -179,8 +195,6 @@ static void lctrMstPhyUpdateOp(lctrConnCtx_t *pCtx) * * \param pOp Begin operation. * - * \return None. - * * \note Scheduler may call this routine multiple times in the following situations: * (1) this BOD is pending and a BOD is inserted before, or (2) a Data PDU is queued * into an empty list. @@ -243,8 +257,6 @@ void lctrMstConnBeginOp(BbOpDesc_t *pOp) * \brief Cleanup a connection operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnCleanupOp(BbOpDesc_t *pOp) @@ -265,8 +277,6 @@ void lctrMstConnCleanupOp(BbOpDesc_t *pOp) * \brief End a connection operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnEndOp(BbOpDesc_t *pOp) @@ -275,9 +285,11 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) BbBleData_t * const pBle = pOp->prot.pBle; BbBleMstConnEvent_t * const pConn = &pBle->op.mstConn; lctrConnCtx_t * const pCtx = pOp->pCtx; - /* Process event completion */ +#if (LL_ENABLE_TESTER == TRUE) + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, pCtx->bleData.chan.txPhy, pCtx->bleData.chan.initTxPhyOptions); +#endif if (!pCtx->connEst && (lctrMstConnIsr.rxFromSlave || (lctrMstConnIsr.consCrcFailed > 0))) { lctrStoreConnTimeoutTerminateReason(pCtx); @@ -293,7 +305,14 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) pCtx->rssi = pConn->rssi; - SchRmSetReference(LCTR_GET_CONN_HANDLE(pCtx)); + if ((pCtx->monitoringState == LCTR_PC_MONITOR_ENABLED) && + (pCtx->lastRxStatus == BB_STATUS_SUCCESS)) + { + if (lctrPcActTbl[pCtx->powerMonitorScheme]) + { + lctrPcActTbl[pCtx->powerMonitorScheme](pCtx); + } + } if (pCtx->checkCisTerm) { @@ -333,7 +352,7 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) pCtx->connUpd.instant = pCtx->eventCounter + ceOffset; /* Use smallest txWindowOffset (i.e. 0) to minimize data loss. */ - uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(0, LCTR_GET_CONN_HANDLE(pCtx), pOp->due); + uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(0, LCTR_GET_CONN_HANDLE(pCtx), pOp->dueUsec); pCtx->connUpd.txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec); lctrPackConnUpdInd(pPdu, &pCtx->connUpd); @@ -363,8 +382,7 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) /*** Update for next operation ***/ - uint32_t anchorPoint = pOp->due; - uint16_t anchorPointOffsetUsec = pOp->dueOffsetUsec; + uint32_t anchorPointUsec = pOp->dueUsec; uint16_t numIntervals = 0; if (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) @@ -378,26 +396,26 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) pBle->chan.initTxPhyOptions = pConn->rxPhyOptions; } + if (pBle->chan.txPhy == BB_PHY_BLE_CODED) + { + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, pBle->chan.txPhy, pBle->chan.initTxPhyOptions); + } + while (TRUE) { numIntervals += 1; pCtx->eventCounter += 1; - uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval) + anchorPointOffsetUsec; - uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec); - int16_t dueOffsetUsec = connInterUsec - BB_TICKS_TO_US(connInter); + uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval); #if (LL_ENABLE_TESTER) if (llTesterCb.connIntervalUs) { - connInterUsec = (numIntervals * llTesterCb.connIntervalUs) + anchorPointOffsetUsec; - connInter = BB_US_TO_BB_TICKS(connInterUsec); - dueOffsetUsec = 0; + connInterUsec = (numIntervals * llTesterCb.connIntervalUs); } #endif /* Advance to next interval. */ - pOp->due = anchorPoint + connInter; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + pOp->dueUsec = anchorPointUsec + connInterUsec; if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) && (pCtx->eventCounter == pCtx->connUpd.instant)) @@ -431,14 +449,14 @@ void lctrMstConnEndOp(BbOpDesc_t *pOp) * \brief Abort a connection operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnAbortOp(BbOpDesc_t *pOp) { lctrConnCtx_t * const pCtx = pOp->pCtx; + LL_TRACE_INFO2("!!! Connection Master BOD aborted, handle=%u, eventCounter=%u", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); + /* Reset operation to state before BOD began */ if (pCtx->emptyPduPend && pCtx->emptyPduFirstAtt) @@ -461,8 +479,6 @@ void lctrMstConnAbortOp(BbOpDesc_t *pOp) * * \param pOp Operation context. * \param status Transmit status. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnTxCompletion(BbOpDesc_t *pOp, uint8_t status) @@ -482,13 +498,12 @@ void lctrMstConnTxCompletion(BbOpDesc_t *pOp, uint8_t status) * \param pOp Operation context. * \param pRxBuf Next receive buffer or NULL to flow control. * \param status Receive status. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) { lctrConnCtx_t * const pCtx = pOp->pCtx; + pCtx->lastRxStatus = status; /* Local state */ uint8_t *pNextRxBuf = NULL; @@ -570,7 +585,7 @@ void lctrMstConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) /*** Scheduler termination ***/ - if (lctrExceededMaxDur(pCtx, pOp->due, pCtx->effConnDurUsec)) + if (lctrExceededMaxDur(pCtx, pOp->dueUsec, pCtx->effConnDurUsec)) { BbSetBodTerminateFlag(); goto PostProcessing; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_slave.c index 913b662ef10..7358c1f79fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave connection ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave connection ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -58,26 +59,24 @@ extern void LctrProcessRxTxAck(lctrConnCtx_t *pCtx, uint8_t *pRxBuf, uint8_t **p * \brief Abort the slave latency and recover connection BOD due time and event counter. * * \param pOp Connection operation. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvAbortSlvLatency(BbOpDesc_t *pOp) { lctrConnCtx_t * const pCtx = pOp->pCtx; - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - uint32_t connInterval = BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval)); + const uint32_t curTime = PalBbGetCurrentTime(); + uint32_t connIntervalUsec = LCTR_CONN_IND_US(pCtx->connInterval); uint32_t count = 0; - if ((pOp->due - curTime) >= LCTR_SCH_MAX_SPAN) + if (BbGetTargetTimeDelta(pOp->dueUsec, curTime) == 0) { /* Slave tries to exit latency while the current BoD is executing, do nothing. */ } - else if (pOp->due - curTime > connInterval) /* Imply (pOp->due - curTime) < LCTR_SCH_MAX_SPAN */ + else if (BbGetTargetTimeDelta(pOp->dueUsec, curTime) > connIntervalUsec) { /* If the connection BOD is due in the future and after the next immediate anchor point, * adjust the event counter. */ - count = LlMathDivideUint32((pOp->due - curTime), connInterval); + count = LlMathDivideUint32(BbGetTargetTimeDelta(pOp->dueUsec, curTime), connIntervalUsec); pCtx->eventCounter -= count; /* Need to adjust the lastChanIdx for channel selection algorithm 1. */ @@ -111,8 +110,6 @@ static void lctrSlvAbortSlvLatency(BbOpDesc_t *pOp) * * \param pCtx Connection context. * \param ignoreOffset txWinOffset will be ignored if TRUE. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx, bool_t ignoreOffset) @@ -132,13 +129,12 @@ static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx, bool_t ignoreOffset) /* Make sure set the anchor point to the instant in the connection update indication. */ const uint16_t numIntervals = pCtx->eventCounter - pCtx->data.slv.lastActiveEvent + 1; const uint32_t timeUsec = LCTR_CONN_IND_US(connIntervalOld * numIntervals); - const uint32_t time = BB_US_TO_BB_TICKS(timeUsec); - pCtx->data.slv.anchorPoint += time; + pCtx->data.slv.anchorPointUsec = pCtx->data.slv.anchorPointUsec + timeUsec; if (pCtx->connUpd.instant != pCtx->data.slv.lastActiveEvent) { /* Save the unsynced time before the connection update. */ - pCtx->data.slv.unsyncedTime = time; + pCtx->data.slv.unsyncedTime = timeUsec; } pCtx->data.slv.lastActiveEvent = pCtx->eventCounter + 1; /* guarantee execution of first connection event. */ @@ -148,19 +144,18 @@ static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx, bool_t ignoreOffset) pCtx->supTimeoutMs = LCTR_CONN_IND_TO_MS(pConnUpdInd->timeout); /*** General setup ***/ + if (ignoreOffset == FALSE) { const uint32_t txWinOffsetUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinOffset); - const uint32_t txWinOffset = BB_US_TO_BB_TICKS(txWinOffsetUsec); const uint32_t txWinSizeUsec = LCTR_CONN_IND_US(pConnUpdInd->txWinSize); const uint32_t wwTxWinOffsetUsec = lctrCalcWindowWideningUsec((txWinOffsetUsec + txWinSizeUsec), pCtx->data.slv.totalAcc); - const uint32_t wwTxWinOffset = BB_US_TO_BB_TICKS(wwTxWinOffsetUsec); /* txWinOffset is relative to anchorPoint. */ - pCtx->data.slv.anchorPoint += txWinOffset; + pCtx->data.slv.anchorPointUsec += txWinOffsetUsec; /* Add additional time due to Tx window offset and subtract WW due to Tx window offset. */ - pOp->due += txWinOffset - wwTxWinOffset; + pOp->dueUsec += txWinOffsetUsec - wwTxWinOffsetUsec; pCtx->data.slv.txWinSizeUsec = txWinSizeUsec; @@ -200,8 +195,6 @@ static void lctrSlvConnUpdateOp(lctrConnCtx_t *pCtx, bool_t ignoreOffset) * \brief Update the channel map. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvChanMapUpdateOp(lctrConnCtx_t *pCtx) @@ -212,6 +205,12 @@ static void lctrSlvChanMapUpdateOp(lctrConnCtx_t *pCtx) /* Delay notification until CE starts. */ pCtx->llcpInstantComp = TRUE; + /* Update the channel map for CIS master as well. */ + if (LctrUpdateCisChanMapFn) + { + LctrUpdateCisChanMapFn(LCTR_GET_CONN_HANDLE(pCtx)); + } + LL_TRACE_INFO2(" >>> Channel map updated, handle=%u, eventCounter=%u <<<", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); } @@ -220,26 +219,41 @@ static void lctrSlvChanMapUpdateOp(lctrConnCtx_t *pCtx) * \brief Update the selected PHY. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvPhyUpdateOp(lctrConnCtx_t *pCtx) { - uint8_t txPhyOld = lctrPhyToPhysBit(pCtx->bleData.chan.txPhy); - uint8_t rxPhyOld = lctrPhyToPhysBit(pCtx->bleData.chan.rxPhy); + BbBleData_t * pBle = &pCtx->bleData; + uint8_t txPhyOld = lctrPhyToPhysBit(pBle->chan.txPhy); + uint8_t rxPhyOld = lctrPhyToPhysBit(pBle->chan.rxPhy); /* Notify host only if PHY changed. */ if ((pCtx->phyUpd.slaveToMasterPhy != LL_PHYS_NONE) && (pCtx->phyUpd.slaveToMasterPhy != txPhyOld)) { - pCtx->bleData.chan.txPhy = lctrPhysBitToPhy(pCtx->phyUpd.slaveToMasterPhy); + pBle->chan.txPhy = lctrPhysBitToPhy(pCtx->phyUpd.slaveToMasterPhy); + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, pCtx->bleData.chan.txPhy, pBle->chan.initTxPhyOptions); pCtx->llcpNotifyMask |= 1 << LCTR_PROC_PHY_UPD; + + if (pBle->chan.txPower == LL_PWR_CTRL_TXPOWER_UNMANAGED) + { + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + LCTR_SET_TXPOWER(pCtx, pBle->chan.txPhy, pLctrRtCfg->defTxPwrLvl); + if (pBle->chan.txPhy == BB_PHY_BLE_CODED) + { + LCTR_SET_TXPOWER(pCtx, LL_PC_PHY_CODED_S2, pLctrRtCfg->defTxPwrLvl); + } + + if ((pCtx->usedFeatSet & LL_FEAT_POWER_CHANGE_IND) && lctrSendPowerChangeIndCback) + { + lctrSendPowerChangeIndCback(pCtx, pBle->chan.txPhy, 0, pBle->chan.txPower, TRUE); + } + } } if ((pCtx->phyUpd.masterToSlavePhy != LL_PHYS_NONE) && (pCtx->phyUpd.masterToSlavePhy != rxPhyOld)) { - pCtx->bleData.chan.rxPhy = lctrPhysBitToPhy(pCtx->phyUpd.masterToSlavePhy); + pBle->chan.rxPhy = lctrPhysBitToPhy(pCtx->phyUpd.masterToSlavePhy); pCtx->llcpNotifyMask |= 1 << LCTR_PROC_PHY_UPD; } @@ -258,8 +272,6 @@ static void lctrSlvPhyUpdateOp(lctrConnCtx_t *pCtx) * \brief Initialize connection event resources. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvInitConnIsr(lctrConnCtx_t *pCtx) @@ -267,7 +279,7 @@ static void lctrSlvInitConnIsr(lctrConnCtx_t *pCtx) pCtx->data.slv.consCrcFailed = 0; pCtx->data.slv.syncWithMaster = FALSE; pCtx->data.slv.rxFromMaster = FALSE; - pCtx->data.slv.firstRxStartTs = 0; + pCtx->data.slv.firstRxStartTsUsec = 0; } /*************************************************************************************************/ @@ -276,8 +288,6 @@ static void lctrSlvInitConnIsr(lctrConnCtx_t *pCtx) * * \param pOp Begin operation. * - * \return None. - * * \note Scheduler may call this routine multiple times in the following situation: * this BOD is pending and a BOD is inserted before. */ @@ -322,13 +332,10 @@ void lctrSlvConnBeginOp(BbOpDesc_t *pOp) * \brief Cleanup a connection operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvConnCleanupOp(BbOpDesc_t *pOp) { - } /*************************************************************************************************/ @@ -336,8 +343,6 @@ void lctrSlvConnCleanupOp(BbOpDesc_t *pOp) * \brief End a connection operation. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvConnEndOp(BbOpDesc_t *pOp) @@ -347,6 +352,10 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp) BbBleSlvConnEvent_t * const pConn = &pBle->op.slvConn; lctrConnCtx_t * const pCtx = pOp->pCtx; +#if (LL_ENABLE_TESTER == TRUE) + pBle->chan.txPower = LCTR_GET_TXPOWER(pCtx, pCtx->bleData.chan.txPhy, pCtx->bleData.chan.initTxPhyOptions); +#endif + /* Process event completion */ if (pCtx->data.slv.abortSlvLatency) { @@ -356,10 +365,19 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp) pCtx->rssi = pConn->rssi; + if ((pCtx->monitoringState == LCTR_PC_MONITOR_ENABLED) && + (pCtx->lastRxStatus == BB_STATUS_SUCCESS)) + { + if (lctrPcActTbl[pCtx->powerMonitorScheme]) + { + lctrPcActTbl[pCtx->powerMonitorScheme](pCtx); + } + } + if (pCtx->data.slv.syncWithMaster) { /* Re-sync to master's clock. */ - pCtx->data.slv.anchorPoint = pCtx->data.slv.firstRxStartTs; + pCtx->data.slv.anchorPointUsec = pCtx->data.slv.firstRxStartTsUsec; pCtx->data.slv.lastActiveEvent = pCtx->eventCounter + 1; pCtx->svtState = LCTR_SVT_STATE_IDLE; @@ -520,10 +538,7 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp) unsyncTimeUsec += pCtx->data.slv.unsyncedTime; uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pCtx->data.slv.totalAcc); - uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec); uint32_t connInterUsec = LCTR_CONN_IND_US(numUnsyncIntervals * pCtx->connInterval); - uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec); - int16_t dueOffsetUsec = (connInterUsec - wwTotalUsec) - BB_TICKS_TO_US(connInter - wwTotal); if (wwTotalUsec >= ((connInterUsec >> 1) - WSF_MAX(LL_BLE_TIFS_US, BbGetSchSetupDelayUs()))) { @@ -534,9 +549,9 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp) } /* Advance to next interval. */ - pOp->due = pCtx->data.slv.anchorPoint + connInter - wwTotal; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); - pOp->minDurUsec = pCtx->data.slv.txWinSizeUsec + pCtx->localConnDurUsec + wwTotalUsec; + pOp->dueUsec = pCtx->data.slv.anchorPointUsec + connInterUsec - wwTotalUsec; + + pOp->minDurUsec = pCtx->data.slv.txWinSizeUsec + pCtx->effConnDurUsec + wwTotalUsec; pConn->rxSyncDelayUsec = pCtx->data.slv.txWinSizeUsec + (wwTotalUsec << 1); if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) && @@ -599,8 +614,6 @@ void lctrSlvConnEndOp(BbOpDesc_t *pOp) * \brief Abort a connection operation. * * \param pOp Aborted operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvConnAbortOp(BbOpDesc_t *pOp) @@ -617,8 +630,6 @@ void lctrSlvConnAbortOp(BbOpDesc_t *pOp) * * \param pOp Operation context. * \param status Transmit status. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvConnTxCompletion(BbOpDesc_t *pOp, uint8_t status) @@ -639,8 +650,6 @@ void lctrSlvConnTxCompletion(BbOpDesc_t *pOp, uint8_t status) * \param pRxBuf Receive buffer. * \param status Receive status. * - * \return None. - * * \note 1. pRxBuf must be freed or placed into a queue by this function. * 2. If the BOD is terminated during this function, no further receive buffer should * remain allocated for the caller to clean up. @@ -652,6 +661,7 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) BbBleData_t * const pBle = &pCtx->bleData; BbBleSlvConnEvent_t * const pConn = &pBle->op.slvConn; + pCtx->lastRxStatus = status; /* Local state */ bool_t loadRxBuf = FALSE; @@ -701,7 +711,7 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) ((status == BB_STATUS_SUCCESS) || (!lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_IGNORE_CRC_ERR_TS) && (status == BB_STATUS_CRC_FAILED)))) { - pCtx->data.slv.firstRxStartTs = pConn->startTs; + pCtx->data.slv.firstRxStartTsUsec = pConn->startTsUsec; pCtx->data.slv.syncWithMaster = TRUE; } @@ -788,7 +798,7 @@ void lctrSlvConnRxCompletion(BbOpDesc_t *pOp, uint8_t *pRxBuf, uint8_t status) /*** Setup for receive ***/ loadRxBuf = ((status == BB_STATUS_CRC_FAILED) || pCtx->rxHdr.md || pCtx->txHdr.md) && - !lctrExceededMaxDur(pCtx, pConn->startTs, SchBleCalcDataPktDurationUsec(pCtx->bleData.chan.txPhy, txLen) + pCtx->effConnDurUsec); + !lctrExceededMaxDur(pCtx, pConn->startTsUsec, SchBleCalcDataPktDurationUsec(pCtx->bleData.chan.txPhy, txLen) + pCtx->effConnDurUsec); /*** Packet post-processing ***/ PostProcessing: diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master.c index cb8faef4f8b..0ed98891e6a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master advertising event ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master advertising event ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -41,27 +42,33 @@ * \brief End an initiate scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstInitiateEndOp(BbOpDesc_t *pOp) { - if (!lctrMstInit.selfTerm) /* implies not a LL_CONN_IND Tx completion */ - { - lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle); + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle); + BbOpDesc_t * pConnBod = &pCtx->connBod; - /* Service RM. */ - SchRmSetReference(lctrMstInit.data.init.connHandle); + if (lctrMstInit.selfTerm) /* implies a LL_CONN_IND Tx completion */ + { + uint16_t numIntervals = 0; + uint32_t anchorPointUsec = pConnBod->dueUsec; - /* Connection cleanup. */ - if (lctrMstInit.data.init.connBodLoaded) + while (TRUE) { - lctrMstInit.data.init.connBodLoaded = FALSE; + if (SchInsertAtDueTime(pConnBod, lctrConnResolveConflict)) + { + break; + } - bool_t result = SchRemove(&pCtx->connBod); - (void)result; - WSF_ASSERT(result); /* non-head BOD always remove-able */ + LL_TRACE_WARN1("!!! Establish CE schedule conflict handle=%u", LCTR_GET_CONN_HANDLE(pCtx)); + + numIntervals++; + pCtx->eventCounter++; + + uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval); + + pConnBod->dueUsec = anchorPointUsec + connInterUsec; } } @@ -86,10 +93,12 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_MST_ADV_EVENT); lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle); + BbOpDesc_t * const pConnBod = &pCtx->connBod; BbBleData_t * const pBle = pOp->prot.pBle; BbBleMstAdvEvent_t * const pScan = &pBle->op.mstAdv; - uint32_t advEndTs = pScan->advStartTs + BB_US_TO_BB_TICKS(LCTR_ADV_PKT_1M_US(pScan->filtResults.pduLen)); + uint32_t advEndTs = pScan->advStartTsUsec + LCTR_ADV_PKT_1M_US(pScan->filtResults.pduLen); + uint32_t refTime = advEndTs; /*** Transmit response PDU processing. ***/ @@ -99,10 +108,6 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) { /* Require peer match. */ } - else if (!lctrMstInit.data.init.connBodLoaded) - { - BbSetBodTerminateFlag(); - } else if (pScan->pTxReqBuf) { /* Update connection indication header with advertiser's address. */ @@ -169,21 +174,30 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) lctrPackAdvbPduHdr(pScan->pTxReqBuf, &lctrMstInit.reqPduHdr); /* Update txWinOffset field in CONN_IND PDU. */ - uint32_t txWinOffsetUsec = BB_TICKS_TO_US(lctrMstInit.data.init.firstCeDue - advEndTs) - LL_BLE_TIFS_US - LCTR_CONN_IND_PKT_1M_US; - uint16_t txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec) - LCTR_DATA_CHAN_DLY; + refTime += LL_BLE_TIFS_US; + refTime += LCTR_CONN_IND_PKT_1M_US; + refTime += LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY); + + /* Now reference time is the start of transmitWindowOffset. */ + uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(LCTR_CONN_IND_US(pCtx->connInterval), LCTR_GET_CONN_HANDLE(pCtx), refTime); + uint16_t txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec); + UINT16_TO_BUF(pScan->pTxReqBuf + LCTR_CONN_IND_TX_WIN_OFFSET, txWinOffset); lctrMstInit.data.init.connInd.txWinOffset = txWinOffset; + /*** Update due time of first CE. ***/ + pConnBod->dueUsec = refTime + txWinOffsetUsec; + #if (LL_ENABLE_TESTER) switch (llTesterCb.connFirstCePos) { case LL_TESTER_FIRST_CE_POS_BEGIN: /* BOD is not scheduled; force time adjustment here. */ - pCtx->connBod.due = advEndTs + BB_US_TO_BB_TICKS(txWinOffsetUsec + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US); + pCtx->connBod.dueUsec = advEndTs + LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY) + txWinOffsetUsec + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US; break; case LL_TESTER_FIRST_CE_POS_END: /* BOD is not scheduled; force time adjustment here. */ - pCtx->connBod.due = advEndTs + BB_US_TO_BB_TICKS(txWinOffsetUsec + LCTR_CONN_IND_US(lctrMstInit.data.init.connInd.txWinSize - 1) + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US); + pCtx->connBod.dueUsec = advEndTs + LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY) + txWinOffsetUsec + LCTR_CONN_IND_US(lctrMstInit.data.init.connInd.txWinSize - 1) + LL_BLE_TIFS_US + LCTR_CONN_IND_PKT_1M_US; break; case LL_TESTER_FIRST_CE_POS_NORMAL: default: @@ -192,35 +206,18 @@ bool_t lctrMstInitiateAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) llTesterCb.connFirstCePos = LL_TESTER_FIRST_CE_POS_NORMAL; #endif - if (txWinOffsetUsec < LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY)) - { - LL_TRACE_WARN1("AE too close to initial CE deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(lctrMstInit.data.init.firstCeDue - advEndTs)); + txConnInd = TRUE; - /* Restart scanning with better initial CE margin. */ - BbSetBodTerminateFlag(); - } - else if (txWinOffset > pCtx->connInterval) - { - LL_TRACE_WARN1("Scan period exceeded initial CE time by deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(advEndTs - lctrMstInit.data.init.firstCeDue)); + /*** Received advertising PDU post-processing. ***/ - /* Restart scanning with CE in the future. */ - BbSetBodTerminateFlag(); + if ((lctrMstInit.reqPduHdr.chSel == LL_CH_SEL_2) && /* local initiator supports CS#2 */ + (pAdvBuf[0] & (1 << LCTR_ADV_HDR_CH_SEL_SHIFT))) /* peer advertiser supports CS#2 */ + { + lctrMstInit.data.init.usedChSel = LL_CH_SEL_2; } else { - txConnInd = TRUE; - - /*** Received advertising PDU post-processing. ***/ - - if ((lctrMstInit.reqPduHdr.chSel == LL_CH_SEL_2) && /* local initiator supports CS#2 */ - (pAdvBuf[0] & (1 << LCTR_ADV_HDR_CH_SEL_SHIFT))) /* peer advertiser supports CS#2 */ - { - lctrMstInit.data.init.usedChSel = LL_CH_SEL_2; - } - else - { - lctrMstInit.data.init.usedChSel = LL_CH_SEL_1; - } + lctrMstInit.data.init.usedChSel = LL_CH_SEL_1; } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master_ae.c index 3cd53b11afe..16c61b1dbe4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_isr_init_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master advertising event ISR callbacks. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master advertising event ISR callbacks. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,8 +45,6 @@ * \brief Reschedule primary scan operation for initiation. * * \param pExtInitCtx Extended initiate context. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtInitiateScanReschedule(lctrExtScanCtx_t *pExtInitCtx) @@ -60,18 +59,18 @@ static void lctrMstExtInitiateScanReschedule(lctrExtScanCtx_t *pExtInitCtx) pOp->minDurUsec = LCTR_MIN_SCAN_USEC; /* Reset due time to start of scan window. */ - pOp->due = pExtInitCtx->data.init.scanWinStart; + pOp->dueUsec = pExtInitCtx->data.init.scanWinStartUsec; if ((pExtInitCtx->data.init.param.scanInterval != pExtInitCtx->data.init.param.scanWindow) && ((pScan->elapsedUsec + pOp->minDurUsec) < LCTR_BLE_TO_US(pExtInitCtx->data.init.param.scanWindow))) { - const uint32_t min = BB_US_TO_BB_TICKS(pScan->elapsedUsec); - const uint32_t max = BB_BLE_TO_BB_TICKS(pExtInitCtx->data.init.param.scanWindow); + const uint32_t min = pScan->elapsedUsec; + const uint32_t max = BB_BLE_TO_US(pExtInitCtx->data.init.param.scanWindow); if (SchInsertEarlyAsPossible(pOp, min, max)) { /* Continue interrupted operation. */ - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pExtInitCtx->data.init.scanWinStart); + pScan->elapsedUsec = BbGetTargetTimeDelta(pOp->dueUsec, pExtInitCtx->data.init.scanWinStartUsec); WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); return; } @@ -88,69 +87,42 @@ static void lctrMstExtInitiateScanReschedule(lctrExtScanCtx_t *pExtInitCtx) { /* Continuous scan. */ SchInsertNextAvailable(pOp); - pExtInitCtx->data.init.scanWinStart = pOp->due; + pExtInitCtx->data.init.scanWinStartUsec = pOp->dueUsec; } else { /* Next scan interval. */ - const uint32_t min = BB_BLE_TO_BB_TICKS(pExtInitCtx->data.init.param.scanInterval); - const uint32_t max = min + BB_BLE_TO_BB_TICKS(pExtInitCtx->data.init.param.scanWindow); + const uint32_t min = BB_BLE_TO_US(pExtInitCtx->data.init.param.scanInterval); + const uint32_t max = min + BB_BLE_TO_US(pExtInitCtx->data.init.param.scanWindow); while (TRUE) { /* Store start of next scan window. */ - pExtInitCtx->data.init.scanWinStart = pOp->due + min; + pExtInitCtx->data.init.scanWinStartUsec = pOp->dueUsec + min; if (SchInsertEarlyAsPossible(pOp, min, max)) { - pScan->elapsedUsec = BB_TICKS_TO_US(pOp->due - pExtInitCtx->data.init.scanWinStart); + pScan->elapsedUsec = BbGetTargetTimeDelta(pOp->dueUsec, pExtInitCtx->data.init.scanWinStartUsec); WSF_ASSERT(pScan->elapsedUsec < pOp->maxDurUsec); break; } else { /* Advance to next scan window. */ - pOp->due = pExtInitCtx->data.init.scanWinStart; + pOp->dueUsec = pExtInitCtx->data.init.scanWinStartUsec; - LL_TRACE_WARN1("!!! Scan schedule conflict at due=%u", pOp->due + min); + LL_TRACE_WARN1("!!! Scan schedule conflict at dueUsec=%u", pOp->dueUsec + min); LL_TRACE_WARN1("!!! scanWindowUsec=%u", LCTR_BLE_TO_US(pExtInitCtx->data.init.param.scanWindow)); } } } } -/*************************************************************************************************/ -/*! - * \brief Handler for pre-initiate scan execution. - * - * \param pOp BB operation descriptor. - * - * \return None. - */ -/*************************************************************************************************/ -void lctrMstExtPreInitiateExecHandler(BbOpDesc_t *pOp) -{ - lctrExtScanCtx_t * const pExtInitCtx = pOp->pCtx; - - if (!pExtInitCtx->shutdown || !pExtInitCtx->selfTerm) - { - /* Setup connection's initial CE now that RM is synchronized BB. This step must be performed - * before initiate's scan operation sets up its executing duration (i.e. "pre-execute"). */ - pExtInitCtx->data.init.firstCeDue = lctrMstConnAdjustOpStart(LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle), - pOp->due, - pOp->minDurUsec, - &pExtInitCtx->data.init.connInd); - pExtInitCtx->data.init.connBodLoaded = TRUE; - } -} - /*************************************************************************************************/ /*! * \brief End a initiate scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtInitiateScanEndOp(BbOpDesc_t *pOp) @@ -185,8 +157,6 @@ void lctrMstExtInitiateScanEndOp(BbOpDesc_t *pOp) * \brief End an auxiliary initiate scan operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstAuxInitiateScanEndOp(BbOpDesc_t *pOp) @@ -210,52 +180,36 @@ void lctrMstAuxInitiateScanEndOp(BbOpDesc_t *pOp) * \brief End an initiate operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtInitiateEndOp(BbOpDesc_t *pOp) { lctrExtScanCtx_t * const pExtInitCtx = pOp->pCtx; + lctrConnCtx_t * pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); + BbOpDesc_t * pConnBod = &pCtx->connBod; - if (!pExtInitCtx->selfTerm && /* Implies not a LL_CONN_IND Tx completion. */ - !pExtInitCtx->auxOpPending) /* Auxiliary EndOp handles cleanup. */ + if (pExtInitCtx->selfTerm && /* LL_CONN_IND Tx Complete. */ + !pExtInitCtx->auxOpPending) /* No aux scan bod pending + * (means that the self termination was generated from a legacy advertisement connection). */ { - lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); + uint16_t numIntervals = 0; + uint32_t anchorPointUsec = pConnBod->dueUsec; - /* Service RM. */ - SchRmSetReference(pExtInitCtx->data.init.connHandle); - - /* Connection cleanup. */ - if (pExtInitCtx->data.init.connBodLoaded) + while (TRUE) { - pExtInitCtx->data.init.connBodLoaded = FALSE; + if (SchInsertAtDueTime(pConnBod, lctrConnResolveConflict)) + { + break; + } - bool_t result = SchRemove(&pCtx->connBod); - (void)result; - WSF_ASSERT(result); /* Non-head BOD always remove-able. */ - } - } - else if (!pExtInitCtx->selfTerm && /* Implies not a LL_CONN_IND Tx completion. */ - pExtInitCtx->auxOpPending) /* AuxBod is scheduled. */ - { - lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); + LL_TRACE_WARN2("!!!Establish CE Schedule conflict handle=%u, evtCtr=%u", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); - if (pExtInitCtx->data.init.connBodLoaded && - pCtx->connBod.due < pExtInitCtx->auxScanBod.due) - { - /* connBod is scheduled and due before auxScanBod, need to reschedule connBod. */ - pExtInitCtx->data.init.connBodLoaded = FALSE; - - bool_t result = SchRemove(&pCtx->connBod); - (void)result; - WSF_ASSERT(result); /* Non-head BOD always remove-able. */ - - pExtInitCtx->data.init.firstCeDue = lctrMstConnAdjustOpStart(LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle), - pExtInitCtx->auxScanBod.due, - pExtInitCtx->auxScanBod.minDurUsec, - &pExtInitCtx->data.init.connInd); - pExtInitCtx->data.init.connBodLoaded = TRUE; + numIntervals++; + pCtx->eventCounter++; + + uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval); + + pConnBod->dueUsec = anchorPointUsec + connInterUsec; } } @@ -267,29 +221,34 @@ void lctrMstExtInitiateEndOp(BbOpDesc_t *pOp) * \brief End an auxiliary initiate operation in the master role. * * \param pOp Completed operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstAuxInitiateEndOp(BbOpDesc_t *pOp) { lctrExtScanCtx_t * const pExtInitCtx = pOp->pCtx; + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); + BbOpDesc_t * pConnBod = &pCtx->connBod; - if (!pExtInitCtx->selfTerm) /* Implies not a LL_CONN_IND Tx completion. */ + if (pExtInitCtx->selfTerm) /* Implies a LL_CONN_IND Tx completion. */ { - lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); - - /* Service RM. */ - SchRmSetReference(pExtInitCtx->data.init.connHandle); + uint16_t numIntervals = 0; + uint32_t anchorPointUsec = pConnBod->dueUsec; - /* Connection cleanup. */ - if (pExtInitCtx->data.init.connBodLoaded) + while (TRUE) { - pExtInitCtx->data.init.connBodLoaded = FALSE; + if (SchInsertAtDueTime(pConnBod, lctrConnResolveConflict)) + { + break; + } + + LL_TRACE_WARN2("!!!Establish CE Schedule conflict handle=%u, evtCtr=%u", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); + + numIntervals++; + pCtx->eventCounter++; - bool_t result = SchRemove(&pCtx->connBod); - (void)result; - WSF_ASSERT(result); /* Non-head BOD always remove-able. */ + uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval); + + pConnBod->dueUsec = anchorPointUsec + connInterUsec; } } @@ -347,12 +306,15 @@ bool_t lctrMstInitiateExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) WSF_ASSERT(pOp->prot.pBle->chan.opType == BB_BLE_OP_MST_ADV_EVENT); lctrExtScanCtx_t *pCtx = pOp->pCtx; + lctrConnCtx_t *pConnCtx = LCTR_GET_CONN_CTX(pCtx->data.init.connHandle); + BbOpDesc_t * const pConnBod = &pConnCtx->connBod; BbBleData_t * const pBle = pOp->prot.pBle; BbBleMstAdvEvent_t * const pScan = &pBle->op.mstAdv; - uint32_t advEndTs = pScan->advStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, - LL_ADV_HDR_LEN + pScan->filtResults.pduLen)); + uint32_t advEndTs = pScan->advStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, + LL_ADV_HDR_LEN + pScan->filtResults.pduLen); + uint32_t refTime = advEndTs; /*** Transmit response PDU processing. ***/ @@ -362,10 +324,6 @@ bool_t lctrMstInitiateExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) { /* Require peer match. */ } - else if (!pCtx->data.init.connBodLoaded) - { - BbSetBodTerminateFlag(); - } else if (pScan->pTxReqBuf) { /* Update connection indication header with advertiser's address. */ @@ -427,46 +385,37 @@ bool_t lctrMstInitiateExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) lctrPackAdvbPduHdr(pScan->pTxReqBuf, &pCtx->reqPduHdr); /* Update txWinOffset field in CONN_IND PDU. */ - uint32_t txWinOffsetUsec = BB_TICKS_TO_US(pCtx->data.init.firstCeDue - advEndTs) - LL_BLE_TIFS_US - - SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); /* Assume conn_ind uses the same PHY as adv_ind. */ - uint16_t txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec) - LCTR_DATA_CHAN_DLY; + refTime += LL_BLE_TIFS_US; + refTime += LCTR_CONN_IND_PKT_1M_US; + refTime += LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY); + + /* Now reference time is the start of transmitWindowOffset. */ + uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(LCTR_CONN_IND_US(pCtx->data.init.connInterval), LCTR_GET_CONN_HANDLE(pConnCtx), refTime); + uint16_t txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec); + UINT16_TO_BUF(pScan->pTxReqBuf + LCTR_CONN_IND_TX_WIN_OFFSET, txWinOffset); pCtx->data.init.connInd.txWinOffset = txWinOffset; - if (txWinOffsetUsec < LCTR_CONN_IND_US(LCTR_DATA_CHAN_DLY)) - { - LL_TRACE_WARN1("AE too close to initial CE deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(pCtx->data.init.firstCeDue - advEndTs)); + /*** Update due time of first CE. ***/ + pConnBod->dueUsec = refTime + txWinOffsetUsec; - /* Restart scanning with better initial CE margin. */ - BbSetBodTerminateFlag(); - } - else if (txWinOffset > pCtx->data.init.connInterval) - { - LL_TRACE_WARN1("Scan period exceeded initial CE time by deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(advEndTs - pCtx->data.init.firstCeDue)); + txConnInd = TRUE; + + /*** Received advertising PDU post-processing. ***/ - /* Restart scanning with CE in the future. */ - BbSetBodTerminateFlag(); + if ((pCtx->reqPduHdr.chSel == LL_CH_SEL_2) && /* local initiator supports CS#2 */ + (pAdvBuf[0] & (1 << LCTR_ADV_HDR_CH_SEL_SHIFT))) /* peer advertiser supports CS#2 */ + { + pCtx->data.init.usedChSel = LL_CH_SEL_2; } else { - txConnInd = TRUE; - - /*** Received advertising PDU post-processing. ***/ - - if ((pCtx->reqPduHdr.chSel == LL_CH_SEL_2) && /* local initiator supports CS#2 */ - (pAdvBuf[0] & (1 << LCTR_ADV_HDR_CH_SEL_SHIFT))) /* peer advertiser supports CS#2 */ - { - pCtx->data.init.usedChSel = LL_CH_SEL_2; - } - else - { - pCtx->data.init.usedChSel = LL_CH_SEL_1; - } + pCtx->data.init.usedChSel = LL_CH_SEL_1; + } - pCtx->data.init.phy = pBle->chan.txPhy; + pCtx->data.init.phy = pBle->chan.txPhy; - pCtx->data.init.isLegacy = TRUE; - } + pCtx->data.init.isLegacy = TRUE; } return txConnInd; @@ -515,8 +464,6 @@ bool_t lctrMstInitiateRxExtAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf * * \param pOp Originating operation. * \param pAdvBuf Received advertising buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrMstInitiateRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf) @@ -551,7 +498,7 @@ void lctrMstInitiateRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t do { /* Confirm auxiliary PHY is supported. */ - bool_t auxPhy = lctrConvertAuxPtrPhyToBbPhy(auxPtr.auxPhy); + uint8_t auxPhy = lctrConvertAuxPtrPhyToBbPhy(auxPtr.auxPhy); if ((auxPhy == BB_PHY_BLE_2M) && ((lmgrCb.features & LL_FEAT_LE_2M_PHY) == 0)) { /* 2M PHY requested, but not supported. */ @@ -565,20 +512,9 @@ void lctrMstInitiateRxExtAdvPktPostProcessHandler(BbOpDesc_t *pOp, const uint8_t pOp->minDurUsec = 0; /* Update primary scan BOD min duration so that secondary scan can be scheduled. */ - /* TODO */ - /* Because of scheduling conflict between preallocated connection bod and aux scan bod, */ - /* connection cannot be established with small connection interval(< 30ms) when coded phy is used. */ - lctrInitiateMsg_t *pInitMsg = (lctrInitiateMsg_t *)pLctrMsg; - if ((auxPhy == BB_PHY_BLE_CODED) && (LCTR_CONN_IND_US(pExtInitCtx->data.init.connInterval) < 30000)) - { - lctrScanNotifyHostInitiateError(LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH, pInitMsg->peerAddrType, pInitMsg->peerAddr); - lctrSendExtInitMsg(pExtInitCtx, LCTR_EXT_INIT_MSG_RESET); - break; - } - - uint32_t endTs = pScan->advStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + pScan->filtResults.pduLen)); - lctrMstAuxDiscoverOpCommit(pExtInitCtx, &auxPtr, pScan->advStartTs, endTs); + uint32_t endTs = pScan->advStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pScan->advRxPhyOptions, LL_ADV_HDR_LEN + pScan->filtResults.pduLen); + lctrMstAuxDiscoverOpCommit(pExtInitCtx, &auxPtr, pScan->advStartTsUsec, endTs); if (pExtInitCtx->auxOpPending) { @@ -629,7 +565,7 @@ bool_t lctrMstInitiateRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf /* AdvA is mandatory. */ if ((extAdvHdrFlags & LL_EXT_HDR_ADV_ADDR_BIT) == 0) { - LL_TRACE_WARN0("Ignoring LL_PDU_AUX_ADV_IND due to missing mandatory advA."); + LL_TRACE_WARN0("Ignoring LL_PDU_AUX_ADV_IND due to missing mandatory advA"); return FALSE; } @@ -645,7 +581,6 @@ bool_t lctrMstInitiateRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf /* Go through the extended PDU filter. */ if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, FALSE, &pAuxScan->filtResults) == FALSE) { - LL_TRACE_WARN0("Ignoring LL_PDU_AUX_ADV_IND due to PDU filtering."); return FALSE; } @@ -662,18 +597,16 @@ bool_t lctrMstInitiateRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf { /* Require peer match. */ } - else if (!pExtInitCtx->data.init.connBodLoaded) - { - BbSetBodTerminateFlag(); - } else if (pAuxScan->pTxAuxReqBuf) { lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pExtInitCtx->data.init.connHandle); + BbOpDesc_t * const pConnBod = &pCtx->connBod; - uint32_t connReqEndTs = pAuxScan->auxStartTs + - BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, LL_ADV_HDR_LEN + advHdr.len) + + uint32_t connReqEndTs = pAuxScan->auxStartTsUsec + + SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxScan->auxRxPhyOptions, LL_ADV_HDR_LEN + advHdr.len) + LL_BLE_TIFS_US + - SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : pAuxScan->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN)); + SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : pAuxScan->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); + uint32_t refTime = connReqEndTs; /* Update auxiliary connection request header's advertiser address. */ uint8_t *pAuxConnReqAdvA = pAuxScan->pTxAuxReqBuf + LL_ADV_HDR_LEN + BDA_ADDR_LEN; @@ -743,45 +676,24 @@ bool_t lctrMstInitiateRxAuxAdvPktHandler(BbOpDesc_t *pOp, const uint8_t *pAdvBuf lctrPackAdvbPduHdr(pExtInitCtx->reqBuf, &pExtInitCtx->reqPduHdr); /* Update txWinOffset field in AUX_CONN_REQ PDU. */ - uint32_t txWinOffsetUsec = BB_TICKS_TO_US(pExtInitCtx->data.init.firstCeDue - connReqEndTs); + uint16_t chanDelay = (pBle->chan.rxPhy == BB_PHY_BLE_CODED) ? LCTR_DATA_CHAN_DLY_AUX_CODED : LCTR_DATA_CHAN_DLY_AUX_UNCODED; + refTime += LCTR_CONN_IND_US(chanDelay); + + /* Now reference time is the start of transmitWindowOffset. */ + uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(LCTR_CONN_IND_US(pCtx->connInterval), LCTR_GET_CONN_HANDLE(pCtx), refTime); uint16_t txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec); - uint16_t chanDelay; - switch (pBle->chan.rxPhy) - { - case BB_PHY_BLE_1M: - case BB_PHY_BLE_2M: - default: - chanDelay = LCTR_DATA_CHAN_DLY_AUX_UNCODED; - break; - case BB_PHY_BLE_CODED: - chanDelay = LCTR_DATA_CHAN_DLY_AUX_CODED; - break; - } - UINT16_TO_BUF(pExtInitCtx->reqBuf + LCTR_CONN_IND_TX_WIN_OFFSET, txWinOffset - chanDelay); - if (txWinOffsetUsec < LCTR_CONN_IND_US(chanDelay)) - { - LL_TRACE_WARN1("AE too close to initial CE deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(pExtInitCtx->data.init.firstCeDue - connReqEndTs)); + UINT16_TO_BUF(pExtInitCtx->reqBuf + LCTR_CONN_IND_TX_WIN_OFFSET, txWinOffset); - /* Restart scanning with better initial CE margin. */ - BbSetBodTerminateFlag(); - } - else if (txWinOffset > pCtx->connInterval) - { - LL_TRACE_WARN1("Scan period exceeded initial CE time by deltaUsec=%u, suppressed LL_CONN_IND delivery", BB_TICKS_TO_US(connReqEndTs - pExtInitCtx->data.init.firstCeDue)); + /*** Update due time of first CE. ***/ + pConnBod->dueUsec = refTime + txWinOffsetUsec; - /* Restart scanning with CE in the future. */ - BbSetBodTerminateFlag(); - } - else - { - txConnInd = TRUE; + txConnInd = TRUE; - pExtInitCtx->data.init.usedChSel = LL_CH_SEL_2; /* LL_PDU_AUX_CONNECT_REQ always uses Channel Selection #2. */ - pExtInitCtx->data.init.phy = pBle->chan.txPhy; + pExtInitCtx->data.init.usedChSel = LL_CH_SEL_2; /* LL_PDU_AUX_CONNECT_REQ always uses Channel Selection #2. */ + pExtInitCtx->data.init.phy = pBle->chan.txPhy; - pExtInitCtx->data.init.isLegacy = FALSE; - } + pExtInitCtx->data.init.isLegacy = FALSE; } return txConnInd; @@ -822,7 +734,7 @@ bool_t lctrMstInitiateRxAuxConnRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBu if (((extAdvHdrFlags & LL_EXT_HDR_ADV_ADDR_BIT) == 0) || ((extAdvHdrFlags & LL_EXT_HDR_TGT_ADDR_BIT) == 0)) { - LL_TRACE_WARN0("LL_PDU_AUX_CONNECT_RSP missing mandatory advA and tgtA."); + LL_TRACE_WARN0("LL_PDU_AUX_CONNECT_RSP missing mandatory advA and tgtA"); } bbBlePduExtFiltParams_t params; @@ -836,7 +748,7 @@ bool_t lctrMstInitiateRxAuxConnRspHandler(BbOpDesc_t *pOp, const uint8_t *pRspBu if (BbBleExtPduFiltCheck(¶ms, &pOp->prot.pBle->pduFilt, TRUE, &pAuxScan->filtResults) == FALSE) { - LL_TRACE_WARN0("LL_PDU_AUX_CONNECT_RSP failed PDU filtering."); + LL_TRACE_WARN0("LL_PDU_AUX_CONNECT_RSP failed PDU filtering"); } if ((pExtInitCtx->extAdvHdr.advMode & (LCTR_ADV_MODE_SCAN_BIT | LCTR_ADV_MODE_CONN_BIT)) != 0) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main.c index 25de41a96c1..563a2bc9bfd 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Main link layer controller implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Main link layer controller implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,6 +30,12 @@ #include "wsf_assert.h" #include "wsf_trace.h" +/************************************************************************************************** + Constants +**************************************************************************************************/ + +#define LCTR_NUM_CH_CLASS_HANDLERS 4 /*!< Number of channel class handlers. */ + /************************************************************************************************** Globals **************************************************************************************************/ @@ -45,14 +52,18 @@ LctrEvtHdlr_t lctrEventHdlrTbl[LCTR_EVENT_TOTAL]; /*! \brief Event message which triggered the current execution context. */ lctrMsgHdr_t *pLctrMsg; +/*! \brief Channel class update handlers. */ +static lctrChClassHdlr_t lctrChClassHandlerTbl[LCTR_NUM_CH_CLASS_HANDLERS]; + +/*! \brief Channel class update handler count. */ +static uint8_t lctrChClassHandlerCnt; + /*! \brief Reset enabled. */ -static bool_t lctrResetEnabled = FALSE; +bool_t lctrResetEnabled = FALSE; /*************************************************************************************************/ /*! * \brief Notify host reset confirm. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyHostResetCnf(void) @@ -71,8 +82,6 @@ static void lctrNotifyHostResetCnf(void) /*************************************************************************************************/ /*! * \brief Set the supporting state bitmask. - * - * \return None. */ /*************************************************************************************************/ void LctrSetSupStates(void) @@ -170,12 +179,6 @@ void LctrSetSupStates(void) LL_SUP_STATE_INIT_SLV; } } - - LL_TRACE_INFO1(" LCTR_DISP_CONN_IND = %c", lctrMsgDispTbl[LCTR_DISP_CONN_IND] ? 'Y' : 'N'); - LL_TRACE_INFO1(" LCTR_DISP_CONN = %c", lctrMsgDispTbl[LCTR_DISP_CONN] ? 'Y' : 'N'); - LL_TRACE_INFO1(" LCTR_DISP_SCAN = %c", lctrMsgDispTbl[LCTR_DISP_SCAN] ? 'Y' : 'N'); - LL_TRACE_INFO1(" LCTR_DISP_INIT = %c", lctrMsgDispTbl[LCTR_DISP_INIT] ? 'Y' : 'N'); - LL_TRACE_INFO1(" LCTR_DISP_ADV = %c", lctrMsgDispTbl[LCTR_DISP_ADV] ? 'Y' : 'N'); } /*************************************************************************************************/ @@ -183,8 +186,6 @@ void LctrSetSupStates(void) * \brief Link layer controller message dispatch handler. * * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void LctrMsgDispatcher(lctrMsgHdr_t *pMsg) @@ -250,8 +251,6 @@ void LctrMsgDispatcher(lctrMsgHdr_t *pMsg) * \brief Link layer controller task event handler. * * \param event Event id. - * - * \return None. */ /*************************************************************************************************/ void LctrEventHandler(uint8_t event) @@ -269,8 +268,6 @@ void LctrEventHandler(uint8_t event) * \brief Notify host HW error indication. * * \param code Error code. - * - * \return None. */ /*************************************************************************************************/ void lctrNotifyHostHwErrInd(uint8_t code) @@ -320,3 +317,137 @@ uint32_t lctrCalcWindowWideningUsec(uint32_t unsyncTimeUsec, uint32_t caPpm) return 0; } } + +/*************************************************************************************************/ +/*! + * \brief Compute new access address. + * + * \return New access address value. + */ +/*************************************************************************************************/ +uint32_t lctrComputeAccessAddr(void) +{ + uint32_t accessAddr = LlMathRandNum(); + + /* + * The following code enforces a pattern to make sure the address meets all requirements + * (including requirements for the LE coded PHY). The pattern is + * + * 0byyyyyy1x 0xxxx1x0 xxxx1x0x xx11x0x1 + * + * with 2^5 choices for the upper six bits. This provides 2^5 * 2^16 = 2097152 variations. + */ + + /* Patterns for upper six bits. The lower row contains complemented values of the upper row. */ + static const uint8_t upperSixBits[] = + { + /* 000010 000100 000101 000110 001000 001100 001101 001110 010000 010001 010011 010111 010110 011000 011100 011110 */ + 0x08, 0x10, 0x14, 0x18, 0x20, 0x30, 0x34, 0x38, 0x40, 0x44, 0x4C, 0x5C, 0x58, 0x60, 0x70, 0x78, + /* 111101 111011 111010 111001 110111 110011 110010 110001 101111 101110 101100 101000 101001 100111 100011 100001 */ + 0xF4, 0xEC, 0xE8, 0xE4, 0xDC, 0xCC, 0xC8, 0xC4, 0xBC, 0xB8, 0xB0, 0xA0, 0xA4, 0x9C, 0x8C, 0x84 + }; + + /* Set the upper six bits. */ + accessAddr = (accessAddr & ~0xFC000000) | (upperSixBits[accessAddr >> 27] << 24); + + /* Set ones with the mask 0b00000010 00000100 00001000 00110001 */ + accessAddr |= 0x02040831; + + /* Clear zeros with the mask 0b00000000 10000001 00000010 00000100 */ + accessAddr &= ~0x00810204; + + return accessAddr; +} + +/*************************************************************************************************/ +/*! + * \brief Compute new seed access address. + * + * \return New seed access address value. + */ +/*************************************************************************************************/ +uint32_t lctrComputeSeedAccessAddr(void) +{ + uint32_t accessAddr = LlMathRandNum(); + + /* + * The following code enforces a pattern to make sure the address meets all requirements. + * The pattern is either the first one or the second one + * + * 0bxxxxxx0x 1yyyyyyy yxxxxxxx xxxxxxxx + * + * with 2^5 choices for the middle 8 bits(indicated by y). This provides 2^5 * 2^ (21 - 4(z)) = 2 ^ 22 = 4194304 variations. + * Z depends LL_MAX_BIS, 6 BISs require 4 bits or 16 combination to assure at least two bits are different. + */ + + /* Patterns for middle 8 bits with 32 combinations. The upper one follows the 1yy0yy10 and lower one follows the 0yy1yy01 */ + static const uint8_t upperSixBits[] = + { + /* 10000010 10000110 10001010 10001110 10100010 10100110 10101010 10101110 11000010 11000110 11001010 11001110 11100010 11100110 11101010 11101110 */ + 0x82, 0x86, 0x8A, 0x8E, 0xA2, 0xA6, 0xAA, 0xAE, 0xC2, 0xC6, 0xCA, 0xCE, 0xE2, 0xE6, 0xEA, 0xEE, + /* 00010001 00010101 00011001 00011101 00110001 00110101 00111001 00111101 01010001 01010101 01011001 01011101 01110001 01110101 01111001 01111101 */ + 0x11, 0x15, 0x19, 0x1D, 0x31, 0x35, 0x39, 0x3D, 0x51, 0x55, 0x59, 0x5D, 0x71, 0x75, 0x79, 0x7D, + }; + + /* Set the middle 8 bits. */ + accessAddr = (accessAddr & ~0x007F8000) | (upperSixBits[accessAddr >> 27] << 15); + + /* Set ones with the mask 0b00000000 10000000 00000000 00000000 */ + accessAddr |= 0x00800000; + + /* Clear zeros with the mask 0b00000010 00000000 00000000 00000000 */ + accessAddr &= ~0x02000000; + + /* TODO add code to make sure two BIG seedAccessAddress in the same device shall differ in at least two bits. */ + + return accessAddr; +} + +/*************************************************************************************************/ +/*! + * \brief Register channel class handler + * + * \param cback Callback function to register. + */ +/*************************************************************************************************/ +void lctrRegisterChClassHandler(lctrChClassHdlr_t cback) +{ + /* Ensure registration does not exceed limits. */ + WSF_ASSERT(lctrChClassHandlerCnt < LCTR_NUM_CH_CLASS_HANDLERS); + lctrChClassHandlerTbl[lctrChClassHandlerCnt++] = cback; +} + +/*************************************************************************************************/ +/*! + * \brief Set channel class. + * + * \param chanMap Channel map (0=bad, 1=usable). + * + * \return Status error code. + * + * Set the channel class. At least 2 bits must be set. + */ +/*************************************************************************************************/ +uint8_t LctrSetChannelClass(uint64_t chanMap) +{ + uint8_t result = LL_SUCCESS; + + lmgrCb.chanClass = chanMap; + + for (unsigned int i = 0; i < lctrChClassHandlerCnt; i++) + { + WSF_ASSERT(lctrChClassHandlerTbl[i]); + + /* Return first error. */ + if (result == LL_SUCCESS) + { + result = lctrChClassHandlerTbl[i](chanMap); + } + else + { + lctrChClassHandlerTbl[i](chanMap); + } + } + + return result; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master.c index a3b60928361..8cd90fe3ceb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller master scanning operation builder implementation file. + * \file + * + * \brief Link layer controller master scanning operation builder implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -45,8 +46,6 @@ lctrMstScanCtx_t lctrMstScan; /*************************************************************************************************/ /*! * \brief Master scan reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstScanResetHandler(void) @@ -61,8 +60,6 @@ static void lctrMstScanResetHandler(void) * \brief Master scan message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstScanDisp(lctrMsgHdr_t *pMsg) @@ -75,8 +72,6 @@ static void lctrMstScanDisp(lctrMsgHdr_t *pMsg) * \brief Advertising report notification. * * \param pRpt Advertising report. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstScanAdvRptNotify(LlAdvReportInd_t *pRpt) @@ -112,7 +107,7 @@ static void lctrMstScanAdvRptNotify(LlAdvReportInd_t *pRpt) * \param pRpt Advertising report indication. * \param pLocalMatch Checks if the received ADV packet matches with local address. * - * \return None. + * \return TRUE if report generated, FALSE if not. */ /*************************************************************************************************/ static bool_t lctrMstCreateAdvRpt(uint8_t *pAdvBuf, LlAdvReportInd_t *pRpt, bool_t *pLocalMatch) @@ -193,8 +188,6 @@ static bool_t lctrMstCreateAdvRpt(uint8_t *pAdvBuf, LlAdvReportInd_t *pRpt, bool /*************************************************************************************************/ /*! * \brief ADVB packet post-processing. - * - * \return None. */ /*************************************************************************************************/ void lctrMstRxAdvBPduHandler(void) @@ -222,8 +215,6 @@ void lctrMstRxAdvBPduHandler(void) /*************************************************************************************************/ /*! * \brief Direct ADVB packet post-processing. - * - * \return None. */ /*************************************************************************************************/ void lctrMstRxDirectAdvBPduHandler(void) @@ -262,8 +253,6 @@ void lctrMstRxDirectAdvBPduHandler(void) /*************************************************************************************************/ /*! * \brief Build scan discovery operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstDiscoverBuildOp(void) @@ -333,7 +322,7 @@ void lctrMstDiscoverBuildOp(void) { /* Attempt to obtain buffer on next advertising operation. */ LL_TRACE_ERR0("Could not allocate advertising buffer"); - // TODO need OOM recovery + /* TODO need OOM recovery */ WSF_ASSERT(FALSE); } @@ -345,7 +334,7 @@ void lctrMstDiscoverBuildOp(void) { /* Attempt to obtain buffer on next advertising operation. */ LL_TRACE_ERR0("Could not allocate advertising buffer"); - // TODO need OOM recovery + /* TODO need OOM recovery */ WSF_ASSERT(FALSE); } @@ -425,7 +414,7 @@ void lctrMstDiscoverBuildOp(void) lctrMstScan.shutdown = FALSE; SchInsertNextAvailable(pOp); - lctrMstScan.scanWinStart = pOp->due; + lctrMstScan.scanWinStartUsec = pOp->dueUsec; } @@ -434,8 +423,6 @@ void lctrMstDiscoverBuildOp(void) * \brief Cleanup resources on advertising operation termination. * * \param pCtx Scan context. - * - * \return None. */ /*************************************************************************************************/ void lctrMstScanCleanupOp(lctrMstScanCtx_t *pCtx) @@ -523,8 +510,6 @@ uint8_t lctrScanChanSelectNext(uint8_t chanIdx, uint8_t chanMap) * \param reason Status code. * \param peerAddrType Peer address type. * \param peerAddr Peer address. - * - * \return None. */ /*************************************************************************************************/ void lctrScanNotifyHostInitiateError(uint8_t reason, uint8_t peerAddrType, uint64_t peerAddr) @@ -555,8 +540,6 @@ void lctrScanNotifyHostInitiateError(uint8_t reason, uint8_t peerAddrType, uint6 * * \param pAdvFilt Advertising report filter data. * \param filtEna Enable advertising report filtering. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvRptEnable(lctrAdvRptFilt_t *pAdvFilt, bool_t filtEna) @@ -688,8 +671,6 @@ bool_t lctrAdvRptCheckDuplicate(lctrAdvRptFilt_t *pAdvFilt, uint64_t hash) * * \param pAdvFilt Advertising report filter data. * \param hash Advertising report hash. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvRptAddEntry(lctrAdvRptFilt_t *pAdvFilt, uint64_t hash) @@ -719,8 +700,6 @@ void lctrAdvRptAddEntry(lctrAdvRptFilt_t *pAdvFilt, uint64_t hash) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstScanInit(void) @@ -747,8 +726,6 @@ void LctrMstScanInit(void) /*************************************************************************************************/ /*! * \brief Set default values for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstScanDefaults(void) @@ -759,8 +736,6 @@ void LctrMstScanDefaults(void) /*************************************************************************************************/ /*! * \brief Increment number of pending advertising reports. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvReportsInc(void) @@ -777,8 +752,6 @@ void lctrAdvReportsInc(void) /*************************************************************************************************/ /*! * \brief Decrement number of pending advertising reports. - * - * \return None. */ /*************************************************************************************************/ void lctrAdvReportsDec(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master_ae.c index ed92d2cee84..40f45ba3bb3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller master scanning operation builder implementation file. + * \file + * + * \brief Link layer controller master scanning operation builder implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,6 +26,7 @@ #include "lctr_int_adv_master.h" #include "lctr_api_adv_master_ae.h" #include "lmgr_api_adv_master_ae.h" +#include "lctr_int_conn_master.h" #include "sch_api.h" #include "sch_api_ble.h" #include "bb_ble_api_reslist.h" @@ -32,19 +34,27 @@ #include "wsf_msg.h" #include "wsf_trace.h" #include "wsf_math.h" +#include "wsf_buf.h" #include "util/bstream.h" - -// TODO Hide in conn only file -#include "lctr_int_conn_master.h" - #include /************************************************************************************************** Globals **************************************************************************************************/ +/*! \brief Extended scan context for 1m */ +lctrExtScanCtx_t lctrMstExtScanOneMCtx; + +/*! \brief Extended scan context for coded */ +lctrExtScanCtx_t lctrMstExtScanCodedCtx; + /*! \brief Extended scan operational context. */ -lctrExtScanCtx_t lctrMstExtScanTbl[LCTR_SCAN_PHY_TOTAL]; // TODO: share memory with legacy lctrMstScan +lctrExtScanCtx_t * lctrMstExtScanTbl[LCTR_SCAN_PHY_TOTAL] = + { + &lctrMstExtScanOneMCtx, + NULL, /* 2M does not have extended scanning functionality. */ + &lctrMstExtScanCodedCtx /* TODO: share memory with legacy lctrMstScan */ + }; /*! \brief Extended scan control block. */ lctrExtScanCtrlBlk_t lctrMstExtScan; @@ -70,13 +80,14 @@ static uint8_t *lctrMstPerScanDataBufTbl[LL_MAX_PER_SCAN]; /*! \brief SyncInfo for periodic sync transfer. */ lctrSyncInfo_t trsfSyncInfo; +/*! \brief Active extended scan contexts. */ +lctrActiveExtScan_t lctrActiveExtScan; + /*************************************************************************************************/ /*! * \brief Master create sync message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstCreateSyncDisp(LctrPerScanMsg_t *pMsg) @@ -91,8 +102,6 @@ static void lctrMstCreateSyncDisp(LctrPerScanMsg_t *pMsg) * \brief Periodic sync transfer recipient message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstTransferSyncDisp(LctrPerScanMsg_t *pMsg) @@ -107,8 +116,6 @@ static void lctrMstTransferSyncDisp(LctrPerScanMsg_t *pMsg) * \brief Periodic scanning message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstPerScanDisp(LctrPerScanMsg_t *pMsg) @@ -135,8 +142,6 @@ static void lctrMstPerScanDisp(LctrPerScanMsg_t *pMsg) /*************************************************************************************************/ /*! * \brief Periodic scanning reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstPerScanResetHandler(void) @@ -147,8 +152,6 @@ static void lctrMstPerScanResetHandler(void) /*************************************************************************************************/ /*! * \brief Master extended scan reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtScanResetHandler(void) @@ -163,8 +166,6 @@ static void lctrMstExtScanResetHandler(void) * \brief Execute common master scan state machine. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtScanExecuteCommonSm(LctrExtScanMsg_t *pMsg) @@ -175,7 +176,7 @@ static void lctrMstExtScanExecuteCommonSm(LctrExtScanMsg_t *pMsg) case LCTR_EXT_SCAN_MSG_DISCOVER_ENABLE: LL_TRACE_INFO2("lctrMstExtScanExecuteCommonSm: numScanEnabled=%u, scanMode=%u, event=DISCOVER_ENABLE", lmgrCb.numScanEnabled, lmgrCb.scanMode); - lctrMstExtScan.scanTermByHost = FALSE; + lctrMstExtScan.scanTermByHost = 0; /* Enable filter. */ lctrMstExtScan.filtDup = pMsg->enable.filtDup; @@ -249,8 +250,6 @@ static void lctrMstExtScanExecuteCommonSm(LctrExtScanMsg_t *pMsg) * \brief Master extended scan message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtScanDisp(LctrExtScanMsg_t *pMsg) @@ -270,7 +269,7 @@ static void lctrMstExtScanDisp(LctrExtScanMsg_t *pMsg) switch (event) { case LCTR_EXT_SCAN_MSG_DISCOVER_DISABLE: - lctrMstExtScan.scanTermByHost = TRUE; + lctrMstExtScan.scanTermByHost++; break; default: break; @@ -310,7 +309,7 @@ static void lctrMstExtScanDisp(LctrExtScanMsg_t *pMsg) WSF_ASSERT(pMsg->hdr.handle < LCTR_SCAN_PHY_TOTAL); if (lctrMstExtScan.enaPhys & (1 << pMsg->hdr.handle)) { - pExtScanCtx = &lctrMstExtScanTbl[pMsg->hdr.handle]; + pExtScanCtx = LCTR_GET_EXT_SCAN_CTX(pMsg->hdr.handle); lctrMstExtScanExecuteSm(pExtScanCtx, event); } } @@ -320,7 +319,7 @@ static void lctrMstExtScanDisp(LctrExtScanMsg_t *pMsg) { if (lctrMstExtScan.enaPhys & (1 << i)) { - pExtScanCtx = &lctrMstExtScanTbl[i]; + pExtScanCtx = LCTR_GET_EXT_SCAN_CTX(i); lctrMstExtScanExecuteSm(pExtScanCtx, event); } } @@ -332,8 +331,6 @@ static void lctrMstExtScanDisp(LctrExtScanMsg_t *pMsg) /*************************************************************************************************/ /*! * \brief Send pending extended advertising report. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstSendPendingAdvRptHandler(void) @@ -343,7 +340,13 @@ static void lctrMstSendPendingAdvRptHandler(void) /* Extended advertising report. */ for (unsigned int i = 0; i < LCTR_SCAN_PHY_TOTAL; i++) { - lctrExtScanCtx_t *pExtScanCtx = &lctrMstExtScanTbl[i]; + if (!(lctrActiveExtScan.scanMask & (1 << i))) + { + continue; + } + + lctrExtScanCtx_t *pExtScanCtx = LCTR_GET_EXT_SCAN_CTX(i); + if (pExtScanCtx->data.scan.auxAdvRptState == LCTR_RPT_STATE_COMP) { @@ -381,6 +384,33 @@ static void lctrMstSendPendingAdvRptHandler(void) } } +/*************************************************************************************************/ +/*! + * \brief Get reference time(due time) of the periodic scan. + * + * \param tmHandle Handle from Topology manager. + * + * \return Due time in microseconds of the periodic scan. + */ +/*************************************************************************************************/ +static uint32_t lctrGetPerScanRefTime(uint8_t tmHandle) +{ + uint32_t refTime = 0; + + WSF_ASSERT(tmHandle >= LL_MAX_CONN); + + lctrPerScanCtx_t *pPerScanCtx = LCTR_GET_PER_SCAN_CTX(tmHandle - LL_MAX_CONN); + BbOpDesc_t * const pOp = &pPerScanCtx->bod; + BbBleData_t * const pBle = &pPerScanCtx->bleData; + + if (pPerScanCtx->enabled && (pBle->chan.opType == BB_BLE_OP_MST_PER_SCAN_EVENT)) + { + refTime = pOp->dueUsec; + } + + return refTime; +} + /*************************************************************************************************/ /*! * \brief Build extended scan discovery operation. @@ -405,7 +435,7 @@ uint8_t lctrMstExtDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx) pOp->protId = BB_PROT_BLE; pOp->prot.pBle = pBle; pOp->endCback = lctrMstExtDiscoverEndOp; - pOp->abortCback = lctrMstExtDiscoverEndOp; + pOp->abortCback = lctrMstExtDiscoverAbortOp; pOp->pCtx = pExtScanCtx; /*** BLE General Setup ***/ @@ -551,21 +581,31 @@ uint8_t lctrMstExtDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx) } /*** Commit operation ***/ + + pOp->minDurUsec = LCTR_MIN_SCAN_USEC; pOp->maxDurUsec = LCTR_BLE_TO_US(pExtScanCtx->scanParam.scanWindow); - if (lmgrCb.numExtScanPhys == 1) + + pExtScanCtx->selfTerm = FALSE; + pExtScanCtx->shutdown = FALSE; + + uint8_t scanPhyIndex = (LCTR_GET_EXT_SCAN_HANDLE(pExtScanCtx) == LCTR_SCAN_PHY_CODED) ? LCTR_SCAN_PHY_CODED : LCTR_SCAN_PHY_1M; + + /* The first scan context is scheduled immediately. */ + /* Otherwise, it will be scheduled from the scheduler end callback. */ + if (lctrActiveExtScan.scanMask == 0) { - pOp->minDurUsec = LCTR_MIN_SCAN_USEC; + SchInsertNextAvailable(pOp); + pExtScanCtx->scanWinStartUsec = pOp->dueUsec; + + lctrActiveExtScan.scanIndex = scanPhyIndex; + lctrActiveExtScan.bodSchMask |= (1 << scanPhyIndex); } else { - pOp->minDurUsec = pOp->maxDurUsec - BB_SCH_SETUP_DELAY_US; + lctrActiveExtScan.bodSchMask &= ~(1 << scanPhyIndex); } - pExtScanCtx->selfTerm = FALSE; - pExtScanCtx->shutdown = FALSE; - - SchInsertNextAvailable(pOp); - pExtScanCtx->scanWinStart = pOp->due; + lctrActiveExtScan.scanMask |= (1 << scanPhyIndex); return LL_SUCCESS; } @@ -630,6 +670,7 @@ uint8_t lctrMstAuxDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx) } /*** BLE Scan Setup: Rx packets ***/ + pAuxScan->isInit = FALSE; pAuxScan->rxAuxAdvCback = lctrMstDiscoverRxAuxAdvPktHandler; @@ -710,8 +751,6 @@ uint8_t lctrMstAuxDiscoverBuildOp(lctrExtScanCtx_t *pExtScanCtx) * \param pAuxPtr Auxiliary Pointer. * \param startTs Start of ADV_EXT_IND packet (offset origin). * \param endTs End of ADV_EXT_IND packet. - * - * \return None. */ /*************************************************************************************************/ void lctrMstAuxDiscoverOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr, uint32_t startTs, uint32_t endTs) @@ -738,10 +777,10 @@ void lctrMstAuxDiscoverOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAu if (auxOffsetUsec < LL_BLE_MAFS_US) { - LL_TRACE_WARN1("Peer requested AUX offset does not meet T_MAFS, actual afsUsec=%u", BB_US_TO_BB_TICKS(pOp->due - endTs)); + LL_TRACE_WARN1("Peer requested AUX offset does not meet T_MAFS, actual afsUsec=%u", pOp->dueUsec - endTs); } - pOp->due = startTs + BB_US_TO_BB_TICKS(auxOffsetUsec); + pOp->dueUsec = startTs + auxOffsetUsec; SchBleCalcAdvOpDuration(pOp, 0); if (SchInsertAtDueTime(pOp, NULL)) @@ -754,12 +793,9 @@ void lctrMstAuxDiscoverOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAu } } - /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtScanInit(void) @@ -779,14 +815,11 @@ void LctrMstExtScanInit(void) LctrMstExtScanDefaults(); lmgrPersistCb.extScanCtxSize = sizeof(lctrExtScanCtx_t); - } /*************************************************************************************************/ /*! * \brief Set default values for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtScanDefaults(void) @@ -800,19 +833,23 @@ void LctrMstExtScanDefaults(void) .scanFiltPolicy = LL_SCAN_FILTER_NONE }; - memset(&lctrMstExtScanTbl, 0, sizeof(lctrMstExtScanTbl)); memset(&lctrMstExtScan, 0, sizeof(lctrMstExtScan)); - lmgrCb.numExtScanPhys = 1; - lctrMstExtScanTbl[LCTR_SCAN_PHY_1M].scanParam = defScanParam; - lctrMstExtScan.enaPhys = 1 << LCTR_SCAN_PHY_1M; - /* Assign buffers. */ for (unsigned int i = 0; i < LCTR_SCAN_PHY_TOTAL; i++) { - lctrMstExtScanTbl[i].pExtAdvData = lctrMstExtScanDataBufTbl[i]; + if (lctrMstExtScanTbl[i]) + { + memset(lctrMstExtScanTbl[i], 0, sizeof(lctrExtScanCtx_t)); + lctrMstExtScanTbl[i]->handle = i; + lctrMstExtScanTbl[i]->pExtAdvData = lctrMstExtScanDataBufTbl[i]; + } } + lmgrCb.numExtScanPhys = 1; + lctrMstExtScanTbl[LCTR_SCAN_PHY_1M]->scanParam = defScanParam; + lctrMstExtScan.enaPhys = 1 << LCTR_SCAN_PHY_1M; + /* Setup timers. */ lctrMsgHdr_t *pMsg; lctrMstExtScan.tmrScanDur.handlerId = lmgrPersistCb.handlerId; @@ -825,6 +862,8 @@ void LctrMstExtScanDefaults(void) /* pMsg->handle = 0; */ /* Unused. */ pMsg->dispId = LCTR_DISP_EXT_SCAN; pMsg->event = LCTR_EXT_SCAN_MSG_TMR_PER_EXP; + + lctrActiveExtScan.scanMask = 0; } /*************************************************************************************************/ @@ -896,9 +935,9 @@ bool_t LctrMstExtScanValidateParam(void) { if (lctrMstExtScan.enaPhys & (1 << i)) { - if (!LmgrIsAddressTypeAvailable(lctrMstExtScanTbl[i].scanParam.ownAddrType)) + if (!LmgrIsAddressTypeAvailable(lctrMstExtScanTbl[i]->scanParam.ownAddrType)) { - LL_TRACE_WARN1("Address type invalid or not available, ownAddrType=%u", lctrMstExtScanTbl[i].scanParam.ownAddrType); + LL_TRACE_WARN1("Address type invalid or not available, ownAddrType=%u", lctrMstExtScanTbl[i]->scanParam.ownAddrType); return FALSE; } } @@ -913,8 +952,6 @@ bool_t LctrMstExtScanValidateParam(void) * \brief Set enabled scanning PHY. * * \param scanPhy Enabled scanning PHY. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtScanSetScanPhy(uint8_t scanPhy) @@ -929,8 +966,6 @@ void LctrMstExtScanSetScanPhy(uint8_t scanPhy) * \brief Clear (disable) scanning PHY. * * \param scanPhy Disabled scanning PHY. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtScanClearScanPhy(uint8_t scanPhy) @@ -948,19 +983,17 @@ void LctrMstExtScanClearScanPhy(uint8_t scanPhy) * \param ownAddrType Address type used by this device. * \param scanFiltPolicy Scan filter policy. * \param pParam Extended scanning parameters. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtScanSetParam(uint8_t scanPhy, uint8_t ownAddrType, uint8_t scanFiltPolicy, const LlExtScanParam_t *pParam) { WSF_ASSERT(scanPhy < LCTR_SCAN_PHY_TOTAL); - lctrMstExtScanTbl[scanPhy].scanParam.scanInterval = pParam->scanInterval; - lctrMstExtScanTbl[scanPhy].scanParam.scanWindow = pParam->scanWindow; - lctrMstExtScanTbl[scanPhy].scanParam.scanType = pParam->scanType; - lctrMstExtScanTbl[scanPhy].scanParam.ownAddrType = ownAddrType; - lctrMstExtScanTbl[scanPhy].scanParam.scanFiltPolicy = scanFiltPolicy; + lctrMstExtScanTbl[scanPhy]->scanParam.scanInterval = pParam->scanInterval; + lctrMstExtScanTbl[scanPhy]->scanParam.scanWindow = pParam->scanWindow; + lctrMstExtScanTbl[scanPhy]->scanParam.scanType = pParam->scanType; + lctrMstExtScanTbl[scanPhy]->scanParam.ownAddrType = ownAddrType; + lctrMstExtScanTbl[scanPhy]->scanParam.scanFiltPolicy = scanFiltPolicy; } /*************************************************************************************************/ @@ -974,22 +1007,7 @@ void LctrMstExtScanSetParam(uint8_t scanPhy, uint8_t ownAddrType, uint8_t scanFi /*************************************************************************************************/ bool_t LctrMstExtScanIsEnabled(uint8_t scanPhy) { - return (lctrMstExtScanTbl[scanPhy].state != LCTR_EXT_SCAN_STATE_DISABLED); -} - -/*************************************************************************************************/ -/*! - * \brief Check if ext scan is using private addresses. - * - * \param scanPhy Extended scanning PHY. - * - * \return True if scan is not disabled, false if not. - */ -/*************************************************************************************************/ -bool_t LctrMstExtScanIsPrivAddr(uint8_t scanPhy) -{ - /* Check the private address bit. */ - return (lctrMstExtScanTbl[scanPhy].scanParam.ownAddrType & LL_ADDR_RANDOM_BIT); + return (lctrMstExtScanTbl[scanPhy]->state != LCTR_EXT_SCAN_STATE_DISABLED); } /*************************************************************************************************/ @@ -998,8 +1016,6 @@ bool_t LctrMstExtScanIsPrivAddr(uint8_t scanPhy) * * \param pExtScanCtx Extended scan context. * \param event Extended scan event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendExtScanMsg(lctrExtScanCtx_t *pExtScanCtx, uint8_t event) @@ -1022,8 +1038,6 @@ void lctrSendExtScanMsg(lctrExtScanCtx_t *pExtScanCtx, uint8_t event) * * \param pCtx Periodic scanning context. * \param event Periodic scan event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendCreateSyncMsg(lctrPerScanCtx_t *pCtx, uint8_t event) @@ -1045,8 +1059,6 @@ void lctrSendCreateSyncMsg(lctrPerScanCtx_t *pCtx, uint8_t event) * * \param pCtx Periodic scanning context. * \param event Periodic advertising event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPerScanMsg(lctrPerScanCtx_t *pCtx, uint8_t event) @@ -1122,8 +1134,6 @@ bool_t LctrMstPerIsSync(uint8_t advSID, uint8_t advAddrType, uint64_t advAddr) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for master create sync. - * - * \return None. */ /*************************************************************************************************/ void LctrMstPerCreateSyncInit(void) @@ -1134,6 +1144,8 @@ void LctrMstPerCreateSyncInit(void) /* Add create sync task message dispatchers. */ lctrMsgDispTbl[LCTR_DISP_PER_CREATE_SYNC] = (LctrMsgDisp_t)lctrMstCreateSyncDisp; + LctrMstPerSyncPending = LctrMstPerIsSyncPending; + /* Set supported features. */ if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_0) { @@ -1144,8 +1156,6 @@ void LctrMstPerCreateSyncInit(void) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for periodic sync transfer recipient. - * - * \return None. */ /*************************************************************************************************/ void LctrMstPerTransferSyncInit(void) @@ -1166,8 +1176,6 @@ void LctrMstPerTransferSyncInit(void) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for master periodic scanning. - * - * \return None. */ /*************************************************************************************************/ void LctrMstPerScanInit(void) @@ -1207,7 +1215,7 @@ uint8_t lctrMstPerScanBuildOp(lctrPerScanCtx_t *pPerScanCtx) /*** General Setup ***/ - pOp->reschPolicy = BB_RESCH_PERIODIC; + pOp->reschPolicy = BB_RESCH_FIXED; pOp->protId = BB_PROT_BLE; pOp->prot.pBle = pBle; pOp->endCback = lctrMstPerScanEndOp; @@ -1215,10 +1223,13 @@ uint8_t lctrMstPerScanBuildOp(lctrPerScanCtx_t *pPerScanCtx) pOp->pCtx = pPerScanCtx; /*** BLE General Setup ***/ + pBle->chan.opType = BB_BLE_OP_MST_PER_SCAN_EVENT; /*** BLE Scan Setup: Rx advertising packet ***/ + /*** BLE Scan Setup: Rx chain packet ***/ + pPerScan->rxPerAdvCback = lctrMstPerScanRxPerAdvPktHandler; pPerScan->rxPerAdvPostCback = lctrMstPerScanRxPerAdvPktPostHandler; @@ -1238,8 +1249,6 @@ uint8_t lctrMstPerScanBuildOp(lctrPerScanCtx_t *pPerScanCtx) * \param pSyncInfo Sync info. * \param startTs Start of AUX_ADV_IND packet (offset origin). * \param endTs End of AUX_ADV_IND packet. - * - * \return None. */ /*************************************************************************************************/ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr, @@ -1268,7 +1277,6 @@ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr pBle->chan.accAddr = pSyncInfo->accAddr; pBle->chan.crcInit = pSyncInfo->crcInit; - /* FIXME: Only if scan enabled */ pBle->chan.txPhy = pBle->chan.rxPhy = lctrConvertAuxPtrPhyToBbPhy(pAuxPtr->auxPhy); #if (LL_ENABLE_TESTER == TRUE) @@ -1279,27 +1287,27 @@ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr #endif /*** Commit operation ***/ + uint32_t syncOffsetUsec; uint32_t offsetUsec = pSyncInfo->syncOffset * ((pSyncInfo->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300); offsetUsec += (LL_SYNC_OFFS_ADJUST_USEC * pSyncInfo->offsetAdjust); - pPerScanCtx->lastAnchorPoint = startTs + BB_US_TO_BB_TICKS(offsetUsec); + pPerScanCtx->lastAnchorPointUsec = startTs + offsetUsec; pPerScanCtx->lastActiveEvent = pPerScanCtx->eventCounter; uint32_t caPpm = lctrCalcTotalAccuracy(pSyncInfo->sca); uint32_t wwUsec = lctrCalcWindowWideningUsec(offsetUsec + ((pSyncInfo->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300), caPpm); syncOffsetUsec = offsetUsec - wwUsec; pPerScanCtx->rxSyncDelayUsec = pBle->op.mstPerScan.rxSyncDelayUsec = (wwUsec << 1) + ((pSyncInfo->offsetUnits == LCTR_OFFS_UNITS_30_USEC) ? 30 : 300); /* rounding compensation */ - int16_t dueOffsetUsec = (offsetUsec - wwUsec) - BB_TICKS_TO_US(BB_US_TO_BB_TICKS(offsetUsec) - BB_US_TO_BB_TICKS(wwUsec)); if (syncOffsetUsec < LL_BLE_MAFS_US) { - LL_TRACE_WARN1("Peer requested AuxPtr offset does not meet T_MAFS, actual afsUsec=%u", BB_US_TO_BB_TICKS(pOp->due - endTs)); + LL_TRACE_WARN1("Peer requested AuxPtr offset does not meet T_MAFS, actual afsUsec=%u", pOp->dueUsec - endTs); return; } - pOp->due = startTs + BB_US_TO_BB_TICKS(syncOffsetUsec); - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); - SchBleCalcAdvOpDuration(pOp, 0); - pPerScanCtx->minDurUsec = pOp->minDurUsec; + pOp->dueUsec = startTs + syncOffsetUsec; + + /* Ensure minimum packet is scheduled; allow PerAdv to schedule tight operations. */ + pPerScanCtx->minDurUsec = pOp->minDurUsec = SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, BB_PHY_OPTIONS_DEFAULT, LL_ADVB_MIN_LEN); uint16_t numUnsyncIntervals = 0; while (TRUE) @@ -1308,9 +1316,10 @@ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr { LL_TRACE_INFO1(" >>> Periodic scan started, handle=%u <<<", LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx)); LL_TRACE_INFO1(" pOp=%08x", pOp); - LL_TRACE_INFO1(" due=%u", pOp->due); + LL_TRACE_INFO1(" dueUsec=%u", pOp->dueUsec); LL_TRACE_INFO1(" eventCounter=%u", pPerScanCtx->eventCounter); - LL_TRACE_INFO1(" pBle->chan.chanIdx=%u", pBle->chan.chanIdx); + LL_TRACE_INFO1(" chanIdx=%u", pBle->chan.chanIdx); + LL_TRACE_INFO1(" pBod=0x%08x", pOp); break; } @@ -1321,19 +1330,19 @@ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr pBle->chan.chanIdx = lctrPeriodicSelectNextChannel(&pPerScanCtx->chanParam, pPerScanCtx->eventCounter); numUnsyncIntervals++; - uint32_t unsyncTimeUsec = BB_TICKS_TO_US(pPerScanCtx->perInter * numUnsyncIntervals); - uint32_t unsyncTime = BB_US_TO_BB_TICKS(unsyncTimeUsec); + uint32_t unsyncTimeUsec = pPerScanCtx->perInterUsec * numUnsyncIntervals; uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, caPpm); - uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec); - dueOffsetUsec = (unsyncTimeUsec - wwTotalUsec) - BB_TICKS_TO_US(unsyncTime - wwTotal); /* Advance to next interval. */ - pOp->due = pPerScanCtx->lastAnchorPoint + unsyncTime - wwTotal; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + pOp->dueUsec = pPerScanCtx->lastAnchorPointUsec + unsyncTimeUsec - wwTotalUsec; + pOp->minDurUsec = pPerScanCtx->minDurUsec + wwTotalUsec; pBle->op.mstPerScan.rxSyncDelayUsec = pPerScanCtx->rxSyncDelayUsec + (wwTotalUsec << 1); } + /* Update topology manager information. */ + SchTmAdd(LCTR_GET_PER_SCAN_TM_HANDLE(pPerScanCtx), pPerScanCtx->perInterUsec, pPerScanCtx->minDurUsec, FALSE, lctrGetPerScanRefTime); + lctrPerCreateSync.createSyncPending = TRUE; } @@ -1342,9 +1351,6 @@ void lctrMstPerScanOpCommit(lctrExtScanCtx_t *pExtScanCtx, lctrAuxPtr_t *pAuxPtr * \brief Commit periodic sync transferred scan operation. * * \param connHandle Connection handle. - * \param ceCounter Reference connection event counter. - * - * \return None. */ /*************************************************************************************************/ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) @@ -1397,25 +1403,25 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) /* Calculate reference time: ceRef + offset. */ refTime = lctrConnGetAnchorPoint(pConnCtx, lctrPerTransferSync.ceRef); - refTime += BB_US_TO_BB_TICKS(offsetUsec); + refTime += offsetUsec; /* refTime needs to be future from the next connection event. */ startTs = lctrConnGetAnchorPoint(pConnCtx, pConnCtx->eventCounter); peC = trsfSyncInfo.eventCounter; - if ((refTime - (startTs + BB_US_TO_BB_TICKS(pConnOp->minDurUsec))) < LCTR_SCH_MAX_SPAN) + if (BbGetTargetTimeDelta(refTime, startTs + pConnOp->minDurUsec) > 0) { - numInterval = (refTime - (startTs + BB_US_TO_BB_TICKS(pConnOp->minDurUsec))) / pPerScanCtx->perInter; - refTime -= numInterval * pPerScanCtx->perInter; + numInterval = BbGetTargetTimeDelta(refTime, startTs + pConnOp->minDurUsec) / pPerScanCtx->perInterUsec; + refTime -= numInterval * pPerScanCtx->perInterUsec; peC -= numInterval; - offsetUsec = BB_TICKS_TO_US(refTime - startTs); + offsetUsec = BbGetTargetTimeDelta(refTime , startTs); } else /* refTime is in the past. */ { - numInterval = 1 + ((startTs + BB_US_TO_BB_TICKS(pConnOp->minDurUsec)) - refTime) / pPerScanCtx->perInter; - refTime += numInterval * pPerScanCtx->perInter; + numInterval = 1 + BbGetTargetTimeDelta(startTs + pConnOp->minDurUsec, refTime)/ pPerScanCtx->perInterUsec; + refTime += numInterval * pPerScanCtx->perInterUsec; peC += numInterval; - offsetUsec = BB_TICKS_TO_US(refTime - startTs); + offsetUsec = BbGetTargetTimeDelta(refTime , startTs); } pPerScanCtx->eventCounter = peC; @@ -1430,7 +1436,7 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) /* Da = |PEc – PEb| × PAI × (CAa + CAc) */ uint32_t deltaPA = ((uint16_t)(peC - lctrPerTransferSync.lastPECounter) < LCTR_MAX_INSTANT) ? (uint16_t)(peC - lctrPerTransferSync.lastPECounter) : 0; - deltaPA *= BB_TICKS_TO_US(pPerScanCtx->perInter); + deltaPA *= pPerScanCtx->perInterUsec; uint32_t dA = lctrCalcWindowWideningUsec(deltaPA, (scaPpmA + scaPpmC)); /* Db = |CEt – CEs| × CI × (CAb + CAc) */ @@ -1443,12 +1449,11 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) LL_TRACE_WARN3("Periodic scan transfer WW=%u: Da=%u, Db=%u", wwUsec, dA, dB); - pPerScanCtx->lastAnchorPoint = startTs + BB_US_TO_BB_TICKS(offsetUsec); + pPerScanCtx->lastAnchorPointUsec = startTs + offsetUsec; pPerScanCtx->lastActiveEvent = pPerScanCtx->eventCounter; pPerScanCtx->initEventCounter = pPerScanCtx->eventCounter; - pOp->due = startTs + BB_US_TO_BB_TICKS(offsetUsec - wwUsec); - pOp->dueOffsetUsec = 0; + pOp->dueUsec = startTs + offsetUsec - wwUsec; SchBleCalcAdvOpDuration(pOp, 0); pPerScanCtx->minDurUsec = pOp->minDurUsec; uint16_t numUnsyncIntervals = 0; @@ -1459,9 +1464,10 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) { LL_TRACE_INFO1(" >>> Periodic scan from transfer started, handle=%u <<<", LCTR_GET_PER_SCAN_HANDLE(pPerScanCtx)); LL_TRACE_INFO1(" pOp=%08x", pOp); - LL_TRACE_INFO1(" due=%u", pOp->due); + LL_TRACE_INFO1(" dueUsec=%u", pOp->dueUsec); LL_TRACE_INFO1(" eventCounter=%u", pPerScanCtx->eventCounter); LL_TRACE_INFO1(" pBle->chan.chanIdx=%u", pBle->chan.chanIdx); + LL_TRACE_INFO1(" pBod=0x%08x", pOp); break; } @@ -1471,16 +1477,19 @@ void lctrMstPerScanTransferOpCommit(uint16_t connHandle) pBle->chan.chanIdx = lctrPeriodicSelectNextChannel(&pPerScanCtx->chanParam, pPerScanCtx->eventCounter); numUnsyncIntervals++; - uint32_t unsyncTimeUsec = BB_TICKS_TO_US(pPerScanCtx->perInter * numUnsyncIntervals); + uint32_t unsyncTimeUsec = pPerScanCtx->perInterUsec * numUnsyncIntervals; dA = lctrCalcWindowWideningUsec((deltaPA + unsyncTimeUsec), (scaPpmA + scaPpmC)); wwUsec = 16 + lctrCalcWindowWideningUsec((dA + dB), (1 + scaPpmA + scaPpmB + scaPpmC)); /* Advance to next interval. */ - pOp->due = pPerScanCtx->lastAnchorPoint + BB_US_TO_BB_TICKS(unsyncTimeUsec - wwUsec); + pOp->dueUsec = pPerScanCtx->lastAnchorPointUsec + unsyncTimeUsec - wwUsec; pOp->minDurUsec = pPerScanCtx->minDurUsec + wwUsec; pBle->op.mstPerScan.rxSyncDelayUsec = pPerScanCtx->rxSyncDelayUsec + (wwUsec << 1); } + + /* Update topology manager information. */ + SchTmAdd(LCTR_GET_PER_SCAN_TM_HANDLE(pPerScanCtx), pPerScanCtx->perInterUsec, pPerScanCtx->minDurUsec, FALSE, lctrGetPerScanRefTime); } /*************************************************************************************************/ @@ -1539,7 +1548,7 @@ lctrPerScanCtx_t *lctrAllocPerScanCtx(void) { lctrPerScanCtx_t *pCtx = LCTR_GET_PER_SCAN_CTX(index); - memset(&lctrMstPerScanTbl[index], 0, sizeof(lctrPerScanCtx_t)); + memset(pCtx, 0, sizeof(lctrPerScanCtx_t)); pCtx->enabled = TRUE; @@ -1585,19 +1594,23 @@ BbOpDesc_t *lctrPerScanResolveConflict(BbOpDesc_t *pNewOp, BbOpDesc_t *pExistOp) /* Only BLE uses periodic scan. */ WSF_ASSERT((pNewOp->protId == BB_PROT_BLE) && (pExistOp->protId == BB_PROT_BLE)); - WSF_ASSERT((pNewOp->prot.pBle->chan.opType == BB_BLE_OP_MST_PER_SCAN_EVENT) && - (pExistOp->prot.pBle->chan.opType == BB_BLE_OP_MST_PER_SCAN_EVENT)); + WSF_ASSERT(pNewOp->prot.pBle->chan.opType == BB_BLE_OP_MST_PER_SCAN_EVENT); + + if (pExistOp->prot.pBle->chan.opType != BB_BLE_OP_MST_PER_SCAN_EVENT) + { + return pExistOp; + } /* Supervision timeout is imminent (2 PI). */ - LL_TRACE_WARN2("Exit timeout=%u, interval=%u", pExistCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000, (uint32_t)(BB_TICKS_TO_US(pExistCtx->perInter) << 1)); - LL_TRACE_WARN2("New timeout=%u, interval=%u", pNewCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000, (uint32_t)(BB_TICKS_TO_US(pExistCtx->perInter) << 1)); - if ((pExistCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000) < (uint32_t)(BB_TICKS_TO_US(pExistCtx->perInter) << 1)) + LL_TRACE_WARN2("Exit timeout=%u, interval=%u", pExistCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000, (uint32_t)(pExistCtx->perInterUsec << 1)); + LL_TRACE_WARN2("New timeout=%u, interval=%u", pNewCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000, (uint32_t)(pExistCtx->perInterUsec << 1)); + if ((pExistCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000) < (uint32_t)(pExistCtx->perInterUsec << 1)) { LL_TRACE_WARN2("!!! Scheduling conflict, imminent SVT: existing handle=%u prioritized over incoming handle=%u", LCTR_GET_PER_SCAN_HANDLE(pExistCtx), LCTR_GET_PER_SCAN_HANDLE(pNewCtx)); return pExistOp; } - if ((pNewCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000) < (uint32_t)(BB_TICKS_TO_US(pNewCtx->perInter) << 1)) + if ((pNewCtx->tmrSupTimeout.ticks * WSF_MS_PER_TICK * 1000) < (uint32_t)(pNewCtx->perInterUsec << 1)) { LL_TRACE_WARN2("!!! Scheduling conflict, imminent SVT: incoming handle=%u prioritized over existing handle=%u", LCTR_GET_PER_SCAN_HANDLE(pNewCtx), LCTR_GET_PER_SCAN_HANDLE(pExistCtx)); return pNewOp; @@ -1605,12 +1618,12 @@ BbOpDesc_t *lctrPerScanResolveConflict(BbOpDesc_t *pNewOp, BbOpDesc_t *pExistOp) /* Less frequent perInterval (4x). */ - if ((LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pExistCtx->perInter)) >> 2) > LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pNewCtx->perInter))) + if ((LCTR_PER_INTER_TO_MS(pExistCtx->perInterUsec) >> 2) > LCTR_PER_INTER_TO_MS(pNewCtx->perInterUsec)) { LL_TRACE_WARN2("!!! Scheduling conflict, PI frequency: existing handle=%u prioritized over incoming handle=%u", LCTR_GET_PER_SCAN_HANDLE(pExistCtx), LCTR_GET_PER_SCAN_HANDLE(pNewCtx)); return pExistOp; } - if ((LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pNewCtx->perInter)) >> 2) > LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pExistCtx->perInter))) + if ((LCTR_PER_INTER_TO_MS(pNewCtx->perInterUsec) >> 2) > LCTR_PER_INTER_TO_MS(pExistCtx->perInterUsec)) { LL_TRACE_WARN2("!!! Scheduling conflict, PI frequency: incoming handle=%u prioritized over existing handle=%u", LCTR_GET_PER_SCAN_HANDLE(pNewCtx), LCTR_GET_PER_SCAN_HANDLE(pExistCtx)); return pNewOp; @@ -1649,8 +1662,6 @@ uint64_t LctrGetPerScanChanMap(uint16_t handle) * * \param status Status. * \param pPerScanCtx Periodic scan context. - * - * \return None. */ /*************************************************************************************************/ void LctrSendPerSyncTrsfRcvdEvt(uint8_t status, lctrPerScanCtx_t *pPerScanCtx) @@ -1670,7 +1681,7 @@ void LctrSendPerSyncTrsfRcvdEvt(uint8_t status, lctrPerScanCtx_t *pPerScanCtx) .advSID = pPerScanCtx->advSID, .addrType = pPerScanCtx->advAddrType, .advPhy = pPerScanCtx->rxPhys, - .perAdvInterval = LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pPerScanCtx->perInter)), + .perAdvInterval = LCTR_PER_INTER_TO_MS(pPerScanCtx->perInterUsec), .advClkAccuracy = pPerScanCtx->sca }; @@ -1688,8 +1699,6 @@ void LctrSendPerSyncTrsfRcvdEvt(uint8_t status, lctrPerScanCtx_t *pPerScanCtx) * * \param syncHandle Periodic sync handle. * \param enable Enable or disable reporting. - * - * \return None. */ /*************************************************************************************************/ void LctrMstPerSetRcvEnable(uint16_t syncHandle, bool_t enable) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave.c index 502a0cd3918..4d3779c30c4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -52,8 +53,6 @@ WSF_CT_ASSERT((BB_FIXED_ADVB_PKT_LEN == 0) || /*************************************************************************************************/ /*! * \brief Slave advertising reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvAdvResetHandler(void) @@ -68,8 +67,6 @@ static void lctrSlvAdvResetHandler(void) * \brief Slave advertising message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvAdvDisp(LctrAdvMsg_t *pMsg) @@ -77,52 +74,9 @@ static void lctrSlvAdvDisp(LctrAdvMsg_t *pMsg) lctrSlvAdvExecuteSm(pMsg->hdr.event); } -/*************************************************************************************************/ -/*! - * \brief Compute new access address. - * - * \return New access address value. - */ -/*************************************************************************************************/ -uint32_t lctrComputeAccessAddr(void) -{ - uint32_t accessAddr = LlMathRandNum(); - - /* - * The following code enforces a pattern to make sure the address meets all requirements - * (including requirements for the LE coded PHY). The pattern is - * - * 0byyyyyy1x 0xxxx1x0 xxxx1x0x xx11x0x1 - * - * with 2^5 choices for the upper six bits. This provides 2^5 * 2^16 = 2097152 variations. - */ - - /* Patterns for upper six bits. The lower row contains complemented values of the upper row. */ - static const uint8_t upperSixBits[] = - { - /* 000010 000100 000101 000110 001000 001100 001101 001110 010000 010001 010011 010111 010110 011000 011100 011110 */ - 0x08, 0x10, 0x14, 0x18, 0x20, 0x30, 0x34, 0x38, 0x40, 0x44, 0x4C, 0x5C, 0x58, 0x60, 0x70, 0x78, - /* 111101 111011 111010 111001 110111 110011 110010 110001 101111 101110 101100 101000 101001 100111 100011 100001 */ - 0xF4, 0xEC, 0xE8, 0xE4, 0xDC, 0xCC, 0xC8, 0xC4, 0xBC, 0xB8, 0xB0, 0xA0, 0xA4, 0x9C, 0x8C, 0x84 - }; - - /* Set the upper six bits. */ - accessAddr = (accessAddr & ~0xFC000000) | (upperSixBits[accessAddr >> 27] << 24); - - /* Set ones with the mask 0b00000010 00000100 00001000 00110001 */ - accessAddr |= 0x02040831; - - /* Clear zeros with the mask 0b00000000 10000001 00000010 00000100 */ - accessAddr &= ~0x00810204; - - return accessAddr; -} - /*************************************************************************************************/ /*! * \brief Scan request post-processing. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvRxScanReq(void) @@ -167,8 +121,6 @@ void lctrSlvRxScanReq(void) * \param peerAddrType Peer address type. * \param peerAddr Peer address. * \param pAdvA Storage for AdvA. - * - * \return None. */ /*************************************************************************************************/ void lctrChooseAdvA(BbBleData_t * const pBle, lctrAdvbPduHdr_t *pPduHdr, @@ -233,8 +185,6 @@ void lctrChooseAdvA(BbBleData_t * const pBle, lctrAdvbPduHdr_t *pPduHdr, * \param peerAddrType Peer address type. * \param peerAddr Peer address. * \param pPeerRpa Storage for peer RPA. - * - * \return None. */ /*************************************************************************************************/ void lctrChoosePeerAddr(BbBleData_t * const pBle, uint8_t ownAddrType, @@ -255,8 +205,6 @@ void lctrChoosePeerAddr(BbBleData_t * const pBle, uint8_t ownAddrType, /*************************************************************************************************/ /*! * \brief Build advertising operation. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAdvBuildOp(void) @@ -345,9 +293,9 @@ void lctrSlvAdvBuildOp(void) break; case LL_ADV_CONN_DIRECT_HIGH_DUTY: /* Advertising interval is determined by LL not host. */ - lmgrSlvAdvCb.advParam.advInterMin = 0; - lmgrSlvAdvCb.advParam.advInterMax = BB_BLE_TO_BB_TICKS(LL_DIR_ADV_INTER_TICKS); - lmgrSlvAdvCb.advTermCntDown = BB_BLE_TO_BB_TICKS(LL_DIR_ADV_DUR_TICKS); + lmgrSlvAdvCb.advParam.advInterMinUsec = 0; + lmgrSlvAdvCb.advParam.advInterMaxUsec = BB_BLE_TO_US(LL_DIR_ADV_INTER_TICKS); + lmgrSlvAdvCb.advTermCntDownUsec = BB_BLE_TO_US(LL_DIR_ADV_DUR_TICKS); pAdv->firstAdvChIdx = 0; /* High duty cycle always start from channel 37. */ /* Fallthrough */ case LL_ADV_CONN_DIRECT_LOW_DUTY: @@ -433,20 +381,13 @@ void lctrSlvAdvBuildOp(void) case LL_ADV_CONN_DIRECT_LOW_DUTY: case LL_ADV_SCAN_UNDIRECT: { - lctrMsgHdr_t *pMsg; + /* Allocate an aligned static array for pAdv->pRxReqBuf */ + static int buffer[(sizeof(lctrMsgHdr_t) + BB_REQ_PDU_MAX_LEN + sizeof(int) - 1) / sizeof(int)]; + lctrMsgHdr_t *pMsg = (lctrMsgHdr_t*)buffer; - if ((pMsg = WsfMsgAlloc(sizeof(lctrMsgHdr_t) + BB_REQ_PDU_MAX_LEN)) != NULL) - { - pAdv->pRxReqBuf = (uint8_t *)(pMsg + 1); /* hide header */ - pAdv->rxReqCback = lctrSlvAdvHandler; - pAdv->rxReqPostCback = lctrSlvAdvPostProcessHandler; - } - else - { - /* Attempt to obtain buffer on next advertising operation. */ - LL_TRACE_ERR0("Could not allocate response buffer"); - // TODO need OOM recovery - } + pAdv->pRxReqBuf = (uint8_t *)(pMsg + 1); /* hide header */ + pAdv->rxReqCback = lctrSlvAdvHandler; + pAdv->rxReqPostCback = lctrSlvAdvPostProcessHandler; break; } case LL_ADV_NONCONN_UNDIRECT: @@ -497,25 +438,18 @@ void lctrSlvAdvBuildOp(void) SchBleCalcAdvOpDuration(pOp, 0); SchInsertNextAvailable(pOp); - LL_TRACE_INFO1("### AdvEvent ### Advertising enabled, due=%u", pOp->due); + LL_TRACE_INFO1("### AdvEvent ### Advertising enabled, dueUsec=%u", pOp->dueUsec); } /*************************************************************************************************/ /*! * \brief Cleanup resources on advertising operation termination. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAdvCleanupOp(void) { - lctrMsgHdr_t *pMsg = (lctrMsgHdr_t *)lctrSlvAdv.bleData.op.slvAdv.pRxReqBuf; - - if (pMsg) - { - /* Recover header. */ - WsfMsgFree(pMsg - 1); - } + /* The storage for pRxReqBuf is a static array. */ + lctrSlvAdv.bleData.op.slvAdv.pRxReqBuf = NULL; LL_TRACE_INFO0("### AdvEvent ### Advertising disabled"); } @@ -523,8 +457,6 @@ void lctrSlvAdvCleanupOp(void) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for advertising slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvAdvInit(void) @@ -544,8 +476,6 @@ void LctrSlvAdvInit(void) /*************************************************************************************************/ /*! * \brief Set default values for advertising slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvAdvDefaults(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave_ae.c index 386811a7182..d8dc6b8e3fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave extended advertising operation builder implementation file. + * \file + * + * \brief Link layer controller slave extended advertising operation builder implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -49,7 +50,7 @@ Globals **************************************************************************************************/ /*! \brief Advertising set table. */ -lctrAdvSet_t *pLctrAdvSetTbl; // TODO: share memory with legacy lctrSlvAdv +lctrAdvSet_t *pLctrAdvSetTbl; /* TODO: share memory with legacy lctrSlvAdv */ /*! \brief Common storage for task message data (parameter passing to action routines). */ LctrExtAdvMsg_t *pLctrSlvExtAdvMsg; @@ -66,22 +67,23 @@ static uint8_t *lctrExtAdvDataBufTbl[LL_MAX_ADV_SETS]; /*! \brief Periodic advertising data buffer table. */ static uint8_t *lctrPerAdvDataBufTbl[LL_MAX_ADV_SETS]; +/*! \brief Slave ACAD message. */ +lctrAcadSlvMsg_t *pLctrAcadSlvMsg; + /************************************************************************************************** Internal functions **************************************************************************************************/ /*************************************************************************************************/ /*! - * \brief Reset acad params - * - * \return None. + * \brief Reset ACAD params */ /*************************************************************************************************/ static void lctrSlvAcadResetHandler(void) { lctrAdvSet_t *pAdvSet; - for (uint8_t handle = 0; handle < pLctrRtCfg->maxAdvSets; handle++) + for (unsigned int handle = 0; handle < pLctrRtCfg->maxAdvSets; handle++) { if ((pAdvSet = lctrFindAdvSet(handle)) != NULL) { @@ -92,24 +94,23 @@ static void lctrSlvAcadResetHandler(void) /*************************************************************************************************/ /*! - * \brief Acad dispatch handler + * \brief ACAD dispatch handler * * \param pMsg Message to be handled. - * - * \return None. */ /*************************************************************************************************/ -static void lctrSlvAcadDisp(lctrChanMapUpdate_t *pMsg) +static void lctrSlvAcadDisp(lctrAcadSlvMsg_t *pMsg) { lctrAdvSet_t *pAdvSet; - LL_TRACE_INFO2("lctrSlvAcadDisp: handle=%u, evt=%u", pMsg->hdr.handle, pMsg->hdr.event); + LL_TRACE_INFO2("lctrSlvAcadDisp: handle=%u, event=%u", pMsg->hdr.handle, pMsg->hdr.event); if (pMsg->hdr.dispId != LCTR_DISP_BCST) { if ((pAdvSet = lctrFindAdvSet(pMsg->hdr.handle)) != NULL) { - pAdvSet->perParam.updChanMask = pMsg->chanMap; + pLctrAcadSlvMsg = pMsg; + lctrSlvAcadExecuteSm(pAdvSet, pMsg->hdr.event); } } @@ -177,7 +178,7 @@ static inline uint16_t lctrCalcMAM(uint16_t a, uint16_t b) /*************************************************************************************************/ static lctrAdvSet_t *lctrAllocAdvSet(uint8_t handle) { - for (uint8_t i = 0; i < pLctrRtCfg->maxAdvSets; i++) + for (unsigned int i = 0; i < pLctrRtCfg->maxAdvSets; i++) { lctrAdvSet_t *pAdvSet = &pLctrAdvSetTbl[i]; @@ -220,8 +221,6 @@ static lctrAdvSet_t *lctrAllocAdvSet(uint8_t handle) * \brief Free an advertising set. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrFreeAdvSet(lctrAdvSet_t *pAdvSet) @@ -262,8 +261,6 @@ lctrAdvSet_t *lctrFindAdvSet(uint8_t handle) * \brief Update auxiliary channel. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSelectNextAuxChannel(lctrAdvSet_t *pAdvSet) @@ -282,8 +279,6 @@ void lctrSelectNextAuxChannel(lctrAdvSet_t *pAdvSet) * \brief Update periodic channel. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSelectNextPerChannel(lctrAdvSet_t *pAdvSet) @@ -326,8 +321,6 @@ uint8_t lctrPeriodicSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t even uint16_t unmapChan = LL_MATH_MOD_37(prn_e & 0xFFFF); - pChanParam->lastChanIdx = unmapChan; - /* remappingIndex */ if (!((UINT64_C(1) << unmapChan) & pChanParam->chanMask)) @@ -343,8 +336,6 @@ uint8_t lctrPeriodicSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t even /*************************************************************************************************/ /*! * \brief Extended advertising reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvExtAdvResetHandler(void) @@ -359,8 +350,6 @@ static void lctrSlvExtAdvResetHandler(void) * \brief Slave extended advertising message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvExtAdvDisp(LctrExtAdvMsg_t *pMsg) @@ -392,8 +381,6 @@ static void lctrSlvExtAdvDisp(LctrExtAdvMsg_t *pMsg) /*************************************************************************************************/ /*! * \brief Scan request post-processing. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvRxExtScanReq(void) @@ -847,7 +834,7 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) if (lmgrGetOpFlag(LL_OP_MODE_FLAG_ENA_ADV_CHAN_RAND)) { - pAdv->firstAdvChIdx = LlMathRandNum() % LL_NUM_CHAN_ADV; + pAdv->firstAdvChIdx = LlMathRandNum() & LL_NUM_CHAN_ADV; } else { @@ -862,9 +849,9 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) if ((pAdvSet->param.advEventProp & LEGACY_HIGH_DUTY) == LEGACY_HIGH_DUTY ) { pAdv->firstAdvChIdx = 0; /* High duty cycle always start from channel 37. */ - pAdvSet->param.priAdvInterMin = 0; - pAdvSet->param.priAdvInterMax = BB_BLE_TO_BB_TICKS(LL_DIR_ADV_INTER_TICKS); - pAdvSet->param.priAdvTermCntDown = BB_US_TO_BB_TICKS(pLctrSlvExtAdvMsg->enable.durMs * 1000); + pAdvSet->param.priAdvInterMinUsec = 0; + pAdvSet->param.priAdvInterMaxUsec = BB_BLE_TO_US(LL_DIR_ADV_INTER_TICKS); + pAdvSet->param.priAdvTermCntDownUsec = pLctrSlvExtAdvMsg->enable.durMs * 1000; } pAdv->txAdvLen = lctrPackLegacyAdvPdu(pAdvSet, pAdvSet->advHdrBuf); @@ -930,9 +917,9 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) if (pLctrSlvExtAdvMsg->enable.durMs) { - pOp->due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()); + pOp->dueUsec = PalBbGetCurrentTime() + BbGetSchSetupDelayUs(); - uint32_t maxTime = BB_US_TO_BB_TICKS(maxStartMs * 1000); + uint32_t maxTime = maxStartMs * 1000; if (!SchInsertEarlyAsPossible(pOp, 0, maxTime)) { LL_TRACE_WARN1("Could not enable ExtAdv operation within given durMs=%u", maxStartMs); @@ -944,7 +931,7 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) SchInsertNextAvailable(pOp); } - LL_TRACE_INFO1("### ExtAdvEvent ### Advertising enabled, due=%u", pOp->due); + LL_TRACE_INFO1("### ExtAdvEvent ### Advertising enabled, dueUsec=%u", pOp->dueUsec); /* Advertising offloading to auxiliary channel. */ if (pAdvSet->pExtAdvAuxPtr) @@ -981,7 +968,7 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) } /* Update AuxPtr now that AUX packet is ready. */ - lctrSlvTxSetupExtAdvHandler(pOp, pOp->due); + lctrSlvTxSetupExtAdvHandler(pOp, pOp->dueUsec); } return LL_SUCCESS; @@ -993,17 +980,15 @@ uint8_t lctrSlvExtAdvBuildOp(lctrAdvSet_t *pAdvSet, uint32_t maxStartMs) * * \param pAdvSet Advertising set. * \param pOp Auxiliary BOD. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAuxRescheduleOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) { - uint32_t auxOffsUsec = BB_US_TO_BB_TICKS(pAdvSet->advBod.minDurUsec + + uint32_t auxOffsUsec = pAdvSet->advBod.minDurUsec + WSF_MAX(BbGetSchSetupDelayUs(), LL_BLE_MAFS_US) + - WSF_MAX(pAdvSet->auxDelayUsec, pLctrRtCfg->auxDelayUsec)); + WSF_MAX(pAdvSet->auxDelayUsec, pLctrRtCfg->auxDelayUsec); - auxOffsUsec = WSF_MIN(auxOffsUsec, BB_US_TO_BB_TICKS(LL_AUX_PTR_MAX_USEC)); + auxOffsUsec = WSF_MIN(auxOffsUsec, LL_AUX_PTR_MAX_USEC); /* Round up auxOffsetUsec if necessary. */ auxOffsUsec = SchBleGetAlignedAuxOffsUsec(auxOffsUsec); @@ -1011,9 +996,9 @@ void lctrSlvAuxRescheduleOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) /* Update BOD duration because extended header length might have been updated. */ SchBleCalcAdvOpDuration(pOp, (pAdvSet->advData.fragPref == LL_ADV_DATA_FRAG_ALLOW) ? pAdvSet->advDataFragLen : 0); - pOp->due = pAdvSet->advBod.due + auxOffsUsec + pLctrRtCfg->auxPtrOffsetUsec; + pOp->dueUsec = pAdvSet->advBod.dueUsec + auxOffsUsec + pLctrRtCfg->auxPtrOffsetUsec; - if (pAdvSet->auxSkipInter == 0) + if (pAdvSet->auxSkipInterUsec == 0) { do { @@ -1023,10 +1008,10 @@ void lctrSlvAuxRescheduleOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) break; } - LL_TRACE_WARN1("!!! AuxAdv schedule conflict at due=%u", BB_TICKS_TO_US(pOp->due)); + LL_TRACE_WARN1("!!! AuxAdv schedule conflict at dueUsec=%u", pOp->dueUsec); LL_TRACE_WARN1("!!! handle=%u", pAdvSet->handle); /* Try next advertising interval. */ - pOp->due += pAdvSet->param.priAdvInterMax; + pOp->dueUsec += pAdvSet->param.priAdvInterMaxUsec; } while (TRUE); } @@ -1035,17 +1020,17 @@ void lctrSlvAuxRescheduleOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) do { /* Link multiple primary channel operations. */ - if (SchInsertLateAsPossible(pOp, 0, pAdvSet->auxSkipInter)) + if (SchInsertLateAsPossible(pOp, 0, pAdvSet->auxSkipInterUsec)) { break; } /* Try next skip interval. */ - pOp->due += pAdvSet->auxSkipInter; + pOp->dueUsec += pAdvSet->auxSkipInterUsec; /* TODO restart advertising at next skip interval or use large skip? */ - LL_TRACE_WARN1("!!! AuxAdv schedule conflict at due=%u", pOp->due); + LL_TRACE_WARN1("!!! AuxAdv schedule conflict at dueUsec=%u", pOp->dueUsec); LL_TRACE_WARN1("!!! handle=%u", pAdvSet->handle); } while (TRUE); @@ -1058,8 +1043,6 @@ void lctrSlvAuxRescheduleOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) * * \param pAdvSet Advertising set. * \param pOp Auxiliary BOD. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvAuxCommitOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) @@ -1068,16 +1051,16 @@ static void lctrSlvAuxCommitOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) if (pAdvSet->param.secAdvMaxSkip) { - uint32_t advEvtDur = BB_US_TO_BB_TICKS(pAdvSet->advBod.minDurUsec); + uint32_t advEvtDurUsec = pAdvSet->advBod.minDurUsec; uint32_t skipTimeUsec = pAdvSet->param.secAdvMaxSkip * /* number of skip events */ - (BB_TICKS_TO_US(pAdvSet->param.priAdvInterMin) + /* minimum interval */ + (pAdvSet->param.priAdvInterMinUsec + /* minimum interval */ ((LL_MAX_ADV_DLY_MS >> 1) * 1000)) + /* average advDelay */ (LL_MAX_ADV_DLY_MS * 1000); /* ensure no overlap due to advDelay */ skipTimeUsec = WSF_MIN(skipTimeUsec, LCTR_AUX_PTR_MAX_OFFSET * 300); /* limit maximum */ - pAdvSet->auxSkipInter = WSF_MAX(BB_US_TO_BB_TICKS(skipTimeUsec), advEvtDur); /* ensure minimum */ + pAdvSet->auxSkipInterUsec = WSF_MAX(skipTimeUsec, advEvtDurUsec); /* ensure minimum */ } lctrSlvAuxRescheduleOp(pAdvSet, pOp); @@ -1088,8 +1071,6 @@ static void lctrSlvAuxCommitOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) * \brief Build auxiliary non-connectable and non-scannable operation. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAuxNonConnNonScanBuildOp(lctrAdvSet_t *pAdvSet) @@ -1106,7 +1087,7 @@ void lctrSlvAuxNonConnNonScanBuildOp(lctrAdvSet_t *pAdvSet) /*** General Setup ***/ - pOp->reschPolicy = BB_RESCH_MOVEABLE_PREFERRED; + pOp->reschPolicy = BB_RESCH_FIXED; pOp->protId = BB_PROT_BLE; pOp->prot.pBle = pBle; pOp->endCback = lctrSlvAuxAdvEndOp; @@ -1183,8 +1164,6 @@ void lctrSlvAuxNonConnNonScanBuildOp(lctrAdvSet_t *pAdvSet) * \brief Build auxiliary scannable operation. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAuxScanBuildOp(lctrAdvSet_t *pAdvSet) @@ -1304,8 +1283,6 @@ void lctrSlvAuxScanBuildOp(lctrAdvSet_t *pAdvSet) * \brief Build auxiliary connectable operation. * * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAuxConnBuildOp(lctrAdvSet_t *pAdvSet) @@ -1418,9 +1395,45 @@ void lctrSlvAuxConnBuildOp(lctrAdvSet_t *pAdvSet) /*************************************************************************************************/ /*! - * \brief Initialize link layer controller resources for advertising slave. + * \brief Host channel class update handler for Periodic Advertising. * - * \return None. + * \param chanMap Updated channel map. + * + * \return Status code. + */ +/*************************************************************************************************/ +static uint8_t lctrSlvPeriodicChClassUpdate(uint64_t chanMap) +{ + lctrChanMapUpdate_t *pMsg; + + /* Update for periodic adv sets */ + for (uint8_t perAdvHandle = 0; perAdvHandle < pLctrRtCfg->maxAdvSets; perAdvHandle++) + { + if (LctrPerAdvEnabled(perAdvHandle) == TRUE) + { + if ((pMsg = (lctrChanMapUpdate_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = (uint16_t)perAdvHandle; + pMsg->hdr.dispId = LCTR_DISP_ACAD; + pMsg->hdr.event = LCTR_ACAD_MSG_CHAN_UPDATE; + pMsg->chanMap = chanMap; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + else + { + LL_TRACE_ERR0("lctrSlvPeriodicChClassUpdate: out of message buffers"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer controller resources for advertising slave. */ /*************************************************************************************************/ void LctrSlvExtAdvInit(void) @@ -1434,8 +1447,10 @@ void LctrSlvExtAdvInit(void) /* Add advertising task event handlers. */ lctrEventHdlrTbl[LCTR_EVENT_RX_SCAN_REQ] = lctrSlvRxExtScanReq; - /* Add acad message dispatchers. */ - lctrMsgDispTbl[LCTR_DISP_ACAD] = (LctrMsgDisp_t) lctrSlvAcadDisp; + /* Add ACAD message dispatchers. */ + lctrMsgDispTbl[LCTR_DISP_ACAD] = (LctrMsgDisp_t)lctrSlvAcadDisp; + + lctrRegisterChClassHandler(lctrSlvPeriodicChClassUpdate); /* Set supported features. */ if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_0) @@ -1449,8 +1464,6 @@ void LctrSlvExtAdvInit(void) /*************************************************************************************************/ /*! * \brief Set default values for advertising slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvExtAdvDefaults(void) @@ -1751,8 +1764,6 @@ uint8_t LctrSetExtAdvSetRandAddr(uint8_t handle, const uint8_t *pAddr) * \param pPduHdr PDU header. * \param pBle BLE operation data. * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrChooseSetAdvA(lctrAdvbPduHdr_t *pPduHdr, BbBleData_t * const pBle, lctrAdvSet_t *pAdvSet) @@ -1815,8 +1826,6 @@ void lctrChooseSetAdvA(lctrAdvbPduHdr_t *pPduHdr, BbBleData_t * const pBle, lctr * \param pPduHdr PDU header. * \param pBle BLE data. * \param pAdvSet Advertising set. - * - * \return None. */ /*************************************************************************************************/ void lctrChooseSetPeerA(lctrAdvbPduHdr_t *pPduHdr, BbBleData_t * const pBle, lctrAdvSet_t *pAdvSet) @@ -1978,20 +1987,20 @@ uint8_t LctrSetExtAdvParam(uint8_t handle, LlExtAdvParam_t *pExtAdvParam) } } - pAdvSet->param.advEventProp = pExtAdvParam->advEventProp; - pAdvSet->param.priAdvInterMin = pExtAdvParam->priAdvInterMin; - pAdvSet->param.priAdvInterMax = pExtAdvParam->priAdvInterMax; - pAdvSet->param.priAdvChanMap = pExtAdvParam->priAdvChanMap; - pAdvSet->param.ownAddrType = pExtAdvParam->ownAddrType; - pAdvSet->param.peerAddrType = pExtAdvParam->peerAddrType; - pAdvSet->param.peerAddr = BstreamToBda64(pExtAdvParam->pPeerAddr); - pAdvSet->param.advFiltPolicy = pExtAdvParam->advFiltPolicy; - pAdvSet->param.advTxPwr = pExtAdvParam->advTxPwr; - pAdvSet->param.priAdvPhy = pExtAdvParam->priAdvPhy; - pAdvSet->param.secAdvMaxSkip = pExtAdvParam->secAdvMaxSkip; - pAdvSet->param.secAdvPhy = pExtAdvParam->secAdvPhy; - pAdvSet->param.advSID = pExtAdvParam->advSID; - pAdvSet->param.scanReqNotifEna = pExtAdvParam->scanReqNotifEna; + pAdvSet->param.advEventProp = pExtAdvParam->advEventProp; + pAdvSet->param.priAdvInterMinUsec = BB_BLE_TO_US(pExtAdvParam->priAdvInterMin); + pAdvSet->param.priAdvInterMaxUsec = BB_BLE_TO_US(pExtAdvParam->priAdvInterMax); + pAdvSet->param.priAdvChanMap = pExtAdvParam->priAdvChanMap; + pAdvSet->param.ownAddrType = pExtAdvParam->ownAddrType; + pAdvSet->param.peerAddrType = pExtAdvParam->peerAddrType; + pAdvSet->param.peerAddr = BstreamToBda64(pExtAdvParam->pPeerAddr); + pAdvSet->param.advFiltPolicy = pExtAdvParam->advFiltPolicy; + pAdvSet->param.advTxPwr = pExtAdvParam->advTxPwr; + pAdvSet->param.priAdvPhy = pExtAdvParam->priAdvPhy; + pAdvSet->param.secAdvMaxSkip = pExtAdvParam->secAdvMaxSkip; + pAdvSet->param.secAdvPhy = pExtAdvParam->secAdvPhy; + pAdvSet->param.advSID = pExtAdvParam->advSID; + pAdvSet->param.scanReqNotifEna = pExtAdvParam->scanReqNotifEna; return LL_SUCCESS; } @@ -2096,7 +2105,6 @@ uint8_t LctrSetPeriodicAdvParam(uint8_t handle, LlPerAdvParam_t *pPerAdvParam) return LL_ERROR_CODE_CMD_DISALLOWED; } -#if 0 uint16_t mafOffset = WSF_MAX(pAdvSet->auxDelayUsec, pLctrRtCfg->auxDelayUsec); uint32_t worstCaseUsec = SchBleCalcPerAdvDurationUsec(pAdvSet->param.secAdvPhy, 0, @@ -2109,7 +2117,6 @@ uint8_t LctrSetPeriodicAdvParam(uint8_t handle, LlPerAdvParam_t *pPerAdvParam) { return LL_ERROR_CODE_PKT_TOO_LONG; } -#endif /* Anonymous advertising is not allowed for periodic advertising. */ if (pAdvSet->param.advEventProp & LL_ADV_EVT_PROP_OMIT_AA_BIT) @@ -2117,8 +2124,8 @@ uint8_t LctrSetPeriodicAdvParam(uint8_t handle, LlPerAdvParam_t *pPerAdvParam) return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - pAdvSet->perParam.advInterMin = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(pPerAdvParam->perAdvInterMin)); /* Convert parameter to bb ticks */ - pAdvSet->perParam.advInterMax = BB_US_TO_BB_TICKS(LCTR_PER_INTER_TO_US(pPerAdvParam->perAdvInterMax)); /* Convert parameter to bb ticks */ + pAdvSet->perParam.advInterMinUsec = LCTR_PER_INTER_TO_US(pPerAdvParam->perAdvInterMin); /* Convert parameter to bb ticks */ + pAdvSet->perParam.advInterMaxUsec = LCTR_PER_INTER_TO_US(pPerAdvParam->perAdvInterMax); /* Convert parameter to bb ticks */ pAdvSet->perParam.advEventProp = pPerAdvParam->perAdvProp; pAdvSet->perParam.advParamReady = TRUE; @@ -2156,10 +2163,10 @@ uint8_t LctrSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const ui return LL_ERROR_CODE_CMD_DISALLOWED; } -#if 0 + uint32_t worstCaseUsec; uint16_t mafOffset = WSF_MAX(pAdvSet->auxDelayUsec, pLctrRtCfg->auxDelayUsec); - uint32_t maxInterval = (pAdvSet->perParam.perAdvEnabled) ? BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter) : BB_TICKS_TO_US(pAdvSet->perParam.advInterMax); + uint32_t maxInterval = (pAdvSet->perParam.perAdvEnabled) ? (pAdvSet->perParam.perAdvInterUsec) : (pAdvSet->perParam.advInterMaxUsec); if (op == LL_ADV_DATA_OP_FRAG_INTER || op == LL_ADV_DATA_OP_FRAG_LAST) /* Intermediate chained data. */ { @@ -2184,7 +2191,6 @@ uint8_t LctrSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const ui { return LL_ERROR_CODE_PKT_TOO_LONG; } -#endif if ((result = lctrSetPerAdvDataSm(pAdvSet, &pAdvSet->perAdvData, op, len, pData)) == LL_SUCCESS) { @@ -2201,8 +2207,6 @@ uint8_t LctrSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const ui * \param handle Advertising handle. * \param enable Set periodic advertising enabled/disabled. * - * \return None. - * * Enable/disable periodic advertising. */ /*************************************************************************************************/ @@ -2331,6 +2335,11 @@ uint8_t LctrRemoveAdvSet(uint8_t handle) return LL_ERROR_CODE_CMD_DISALLOWED; } + if (pAdvSet->removeCback) + { + pAdvSet->removeCback(handle); + } + lctrFreeAdvSet(pAdvSet); return LL_SUCCESS; @@ -2473,8 +2482,6 @@ uint8_t LctrSetExtAdvTxPhyOptions(uint8_t handle, uint8_t priPhyOpts, uint8_t se * * \param pAdvSet Advertising set. * \param event Extended advertising event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendAdvSetMsg(lctrAdvSet_t *pAdvSet, uint8_t event) @@ -2496,8 +2503,6 @@ void lctrSendAdvSetMsg(lctrAdvSet_t *pAdvSet, uint8_t event) * \brief Slave periodic advertising message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvPeriodicAdvDisp(LctrPerAdvMsg_t *pMsg) @@ -2532,8 +2537,6 @@ static void lctrSlvPeriodicAdvDisp(LctrPerAdvMsg_t *pMsg) * * \param pAdvSet Advertising set. * \param event Periodic advertising event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendPeriodicAdvSetMsg(lctrAdvSet_t *pAdvSet, uint8_t event) @@ -2554,7 +2557,9 @@ void lctrSendPeriodicAdvSetMsg(lctrAdvSet_t *pAdvSet, uint8_t event) /*! * \brief Get status of periodic adv handle. * - * \return returns True if periodic advertising is running on that handle, False if not + * \param handle Advertising handle. + * + * \return True if periodic advertising is running on that handle, False if not */ /*************************************************************************************************/ bool_t LctrIsPerAdvEnabled(uint8_t handle) @@ -2573,8 +2578,6 @@ bool_t LctrIsPerAdvEnabled(uint8_t handle) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for periodic advertising slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvPeriodicAdvInit(void) @@ -2601,20 +2604,18 @@ void LctrSlvPeriodicAdvInit(void) * * \param pAdvSet Advertising set. * \param pOp Periodic BOD. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvPeriodicCommitOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pOp) { - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - uint32_t offsetUsec = SchRmGetOffsetUsec(BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter), + const uint32_t curTime = PalBbGetCurrentTime(); + uint32_t offsetUsec = SchRmGetOffsetUsec(pAdvSet->perParam.perAdvInterUsec, LL_MAX_CONN + LCTR_GET_EXT_ADV_INDEX(pAdvSet), curTime); /* RM is shared by connections and periodic advertising. */ - pOp->due = curTime + BB_US_TO_BB_TICKS(offsetUsec); + pOp->dueUsec = curTime + offsetUsec; /*** Commit operation ***/ - uint32_t anchorPoint = pOp->due; + uint32_t anchorPointUsec = pOp->dueUsec; uint16_t numIntervals = 0; while (TRUE) @@ -2629,16 +2630,13 @@ static void lctrSlvPeriodicCommitOp(lctrAdvSet_t *pAdvSet, BbOpDesc_t * const pO numIntervals += 1; pAdvSet->perParam.perEventCounter += 1; - uint32_t perInterUsec = numIntervals * BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter); - uint32_t perInter = BB_US_TO_BB_TICKS(perInterUsec); - int16_t dueOffsetUsec = perInterUsec - BB_TICKS_TO_US(perInter); + uint32_t perInterUsec = numIntervals * pAdvSet->perParam.perAdvInterUsec; /* Advance to next interval. */ - pOp->due = anchorPoint + perInter; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + pOp->dueUsec = anchorPointUsec + perInterUsec; } - LL_TRACE_INFO1("### ExtAdvEvent ### Periodic advertising enabled, due=%u", pOp->due); + LL_TRACE_INFO1("### ExtAdvEvent ### Periodic advertising enabled, dueUsec=%u", pOp->dueUsec); } /*************************************************************************************************/ @@ -2661,7 +2659,7 @@ uint8_t lctrSlvPeriodicAdvBuildOp(lctrAdvSet_t *pAdvSet) /*** General Setup ***/ - pOp->reschPolicy = BB_RESCH_PERIODIC; + pOp->reschPolicy = BB_RESCH_FIXED; pOp->protId = BB_PROT_BLE; pOp->prot.pBle = pBle; pOp->endCback = lctrSlvPeriodicAdvEndOp; @@ -2721,12 +2719,11 @@ uint8_t lctrSlvPeriodicAdvBuildOp(lctrAdvSet_t *pAdvSet) /*** Commit operation ***/ SchBleCalcAdvOpDuration(pOp, 0); - uint32_t interMinUsec = BB_TICKS_TO_US(pAdvSet->perParam.advInterMin); - uint32_t interMaxUsec = BB_TICKS_TO_US(pAdvSet->perParam.advInterMax); + uint32_t interMinUsec = pAdvSet->perParam.advInterMinUsec; + uint32_t interMaxUsec = pAdvSet->perParam.advInterMaxUsec; uint32_t durUsec = pOp->minDurUsec; uint32_t perInterUsec; -#if 0 /* Make sure the worst case advertising duration can make the intervals. */ uint16_t mafOffset = WSF_MAX(pAdvSet->auxDelayUsec, pLctrRtCfg->auxDelayUsec); uint32_t worstCaseUsec = SchBleCalcPerAdvDurationUsec(pAdvSet->param.secAdvPhy, @@ -2746,7 +2743,6 @@ uint8_t lctrSlvPeriodicAdvBuildOp(lctrAdvSet_t *pAdvSet) { interMinUsec = worstCaseUsec; } -#endif /* Max interval is preferred in resource manager. */ if (!SchRmAdd(LCTR_GET_PER_RM_HANDLE(pAdvSet), SCH_RM_PREF_CAPACITY, interMinUsec, interMaxUsec, durUsec, &perInterUsec, lctrGetPerRefTime)) @@ -2754,7 +2750,7 @@ uint8_t lctrSlvPeriodicAdvBuildOp(lctrAdvSet_t *pAdvSet) return LL_ERROR_CODE_LIMIT_REACHED; } - pAdvSet->perParam.perAdvInter = BB_US_TO_BB_TICKS(perInterUsec); + pAdvSet->perParam.perAdvInterUsec = perInterUsec; lctrSlvPeriodicCommitOp(pAdvSet, pOp); return LL_SUCCESS; @@ -2762,12 +2758,12 @@ uint8_t lctrSlvPeriodicAdvBuildOp(lctrAdvSet_t *pAdvSet) /*************************************************************************************************/ /*! - * \brief Get reference time(due time) of the periodic advertising. + * \brief Get reference time (due time) of the periodic advertising. * * \param perHandle Periodic advertising handle. * \param pDurUsec Pointer to duration of the BOD. * - * \return Due time in BB ticks of the periodic advertising handle. + * \return Due time in microseconds of the periodic advertising handle. */ /*************************************************************************************************/ uint32_t lctrGetPerRefTime(uint8_t perHandle, uint32_t *pDurUsec) @@ -2780,7 +2776,7 @@ uint32_t lctrGetPerRefTime(uint8_t perHandle, uint32_t *pDurUsec) pAdvSet = &pLctrAdvSetTbl[perHandle - LL_MAX_CONN]; if (pAdvSet->perParam.perState == LCTR_PER_ADV_STATE_ENABLED) { - refTime = pAdvSet->perParam.perAdvBod.due; + refTime = pAdvSet->perParam.perAdvBod.dueUsec; if (pDurUsec) { *pDurUsec = pAdvSet->perParam.perAdvBod.minDurUsec; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis.c new file mode 100644 index 00000000000..86a91a7acc7 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis.c @@ -0,0 +1,1426 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller broadcast isochronous main implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis.h" +#include "lctr_int_iso.h" +#include "lctr_int_bis_master.h" +#include "wsf_assert.h" +#include "wsf_buf.h" +#include "wsf_math.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Queue header. */ +#define LCTR_Q_ELEM_LEN 4 + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief BIS context table. */ +lctrBisCtx_t *pLctrBisTbl; + +/*! \brief BIG context table. */ +lctrBigCtx_t *pLctrBigTbl; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Assemble BIS Data PDU. + * + * \param pBuf Buffer to pack the Data PDU header. + * \param pduLen PDU length. + * \param llid LLID of PDU. + * \param pSegHdr Segmentation header or NULL if not required. + * + * \return Length of header. + */ +/*************************************************************************************************/ +static uint8_t lctrAssembleBisDataPdu(uint8_t *pBuf, uint16_t pduLen, LlIsoLlid_t llid, lctrIsoSegHdr_t *pSegHdr) +{ + uint8_t hdrLen; + + /* All additional fields must be zero'ed since flow control bits will be or'ed in at transmit. */ + lctrBisDataPduHdr_t dataHdr = + { + .llid = llid, + .cssn = 0, /* Completed in ISR. */ + .cstf = 0, /* Completed in ISR. */ + .len = pduLen + }; + + hdrLen = lctrBisPackDataPduHdr(pBuf, &dataHdr); + + if (pSegHdr) + { + hdrLen += lctrIsoPackSegHdr(pBuf, pSegHdr); + } + + return hdrLen; +} + +/*************************************************************************************************/ +/*! + * \brief Fragment an ISO SDU into a Data PDU descriptor. + * + * \param pBisCtx BIS context. + * \param pIsoHdr ISO SDU header. + * \param pIsoBuf ISO SDU Buffer. + * \param pDesc Fragmentation descriptor. + */ +/*************************************************************************************************/ +static void lctrBisFragmentIsoSdu(lctrBisCtx_t *pBisCtx, lctrIsoHdr_t *pIsoHdr, uint8_t *pIsoBuf, lctrIsoTxBufDesc_t *pDesc) +{ + lctrBigCtx_t *pBigCtx = pBisCtx->pBigCtx; + + pDesc->isoLen = pIsoHdr->sduLen; + pDesc->fragLen = pBisCtx->pBigCtx->maxPdu; + pDesc->fragCnt = 0; + pDesc->pIsoSdu = pIsoBuf; + pDesc->pPduBuf = pIsoBuf + (HCI_ISO_HDR_LEN + HCI_ISO_DL_MIN_LEN) + ((pIsoHdr->tsFlag) ? HCI_ISO_TS_LEN : 0); + + uint8_t *pSduBuf = pDesc->pPduBuf; + uint16_t fragOffset = 0; + + if (pDesc->isoLen > 0) + { + while (fragOffset < pDesc->isoLen) + { + const uint16_t dataRem = pDesc->isoLen - fragOffset; + const uint16_t fragSize = WSF_MIN(dataRem, pDesc->fragLen); + fragOffset += fragSize; + + LlIsoLlid_t llid; + + if (pBigCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + llid = (fragOffset == pDesc->isoLen) ? LL_LLID_ISO_UNF_END_PDU : LL_LLID_ISO_UNF_CONT_PDU; + } + else + { + llid = LL_LLID_ISO_FRA_PDU; + } + + pDesc->frag[pDesc->fragCnt].hdrLen = lctrAssembleBisDataPdu(pDesc->frag[pDesc->fragCnt].hdr, fragSize, llid, NULL); + + uint64_t pktCtr = (pBisCtx->pBigCtx->eventCounter * pBisCtx->pBigCtx->bn) + pDesc->fragCnt; + pBisCtx->chan.enc.pTxPktCounter = &pktCtr; + + /* Set the new packet counter for inline encryption. */ + if (lctrSetEncryptPktCountHdlr) + { + lctrSetEncryptPktCountHdlr(&pBisCtx->chan.enc, pktCtr); + } + + if (lctrPktEncryptHdlr && + lctrPktEncryptHdlr(&pBisCtx->chan.enc, + pDesc->frag[pDesc->fragCnt].hdr, + pSduBuf, + pDesc->frag[pDesc->fragCnt].trl)) + { + pDesc->frag[pDesc->fragCnt].trlLen = LL_DATA_MIC_LEN; + + #if (LL_ENABLE_TESTER) + pDesc->frag[pDesc->fragCnt].trl[0] ^= (llTesterCb.pktMic >> 0) & 0xFF; + pDesc->frag[pDesc->fragCnt].trl[1] ^= (llTesterCb.pktMic >> 8) & 0xFF; + pDesc->frag[pDesc->fragCnt].trl[2] ^= (llTesterCb.pktMic >> 16) & 0xFF; + pDesc->frag[pDesc->fragCnt].trl[3] ^= (llTesterCb.pktMic >> 24) & 0xFF; + #endif + } + else + { + pDesc->frag[pDesc->fragCnt].trlLen = 0; + } + + pSduBuf += fragSize; + pDesc->fragCnt++; + } + } + else + { + /* Zero length SDU. */ + + pDesc->frag[0].hdrLen = lctrAssembleBisDataPdu(pDesc->frag[0].hdr, 0, LL_LLID_ISO_UNF_END_PDU, NULL); + pDesc->frag[0].trlLen = 0; + + pDesc->fragCnt = 1; + } +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a BIG context. + * + * \param bigHandle BIG handle. + * + * \return BIG context or NULL if at capacity. + */ +/*************************************************************************************************/ +lctrBigCtx_t *lctrAllocBigCtx(uint8_t bigHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if (!pBigCtx->enabled) + { + memset(pBigCtx, 0, sizeof(lctrBigCtx_t)); + + pBigCtx->enabled = TRUE; + pBigCtx->handle = bigHandle; + + return pBigCtx; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Free a BIG context. + * + * \param pBigCtx BIG context to free. + */ +/*************************************************************************************************/ +void lctrFreeBigCtx(lctrBigCtx_t *pBigCtx) +{ + WSF_ASSERT(pBigCtx->enabled); + + pBigCtx->enabled = FALSE; + + /* Free all BIS context associated with the BIG. */ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t *pBisCtx = pBigCtx->pBisCtx[i]; + + switch (pBigCtx->role) + { + case LL_ROLE_SLAVE: + lctrBisSetDataPath(pBisCtx, LL_ISO_DATA_DIR_INPUT, LL_ISO_DATA_PATH_DISABLED); + lctrNotifyIsoTxComplete(pBigCtx); + break; + case LL_ROLE_MASTER: + lctrBisSetDataPath(pBisCtx, LL_ISO_DATA_DIR_OUTPUT, LL_ISO_DATA_PATH_DISABLED); + break; + default: + break; + } + + lctrFreeBisCtx(pBisCtx); + } + + /* Flush BIG Control PDUs. */ + switch (pBigCtx->role) + { + case LL_ROLE_SLAVE: + while (!WsfQueueEmpty(&pBigCtx->roleData.slv.txCtrlQ)) + { + lctrBigTxCtrlQueuePopCleanup(pBigCtx); + } + break; + case LL_ROLE_MASTER: + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if the periodic advertising handle is associated with another BIG. + * + * \param advHandle Periodic advertising handle. + * + * \return TRUE if periodic advertising handle is associated with another BIG, otherwise FALSE. + */ +/*************************************************************************************************/ +uint8_t lctrBigIsPerAdvUsed(uint8_t advHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if ((pBigCtx->enabled) && + (pBigCtx->role == LL_ROLE_SLAVE) && + (pBigCtx->roleData.slv.pAdvSet)) + { + return TRUE; + } + } + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Find a BIG by BIG handle. + * + * \param bigHandle BIG handle. + * + * \return BIG context or NULL if not found. + */ +/*************************************************************************************************/ +lctrBigCtx_t *lctrFindBigByHandle(uint8_t bigHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if ((pBigCtx->enabled) && + (pBigCtx->handle == bigHandle)) + { + return pBigCtx; + } + } + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Find a BIG by SyncHandle. + * + * \param syncHandle BIG sync handle. + * + * \return BIG context or NULL if not found. + */ +/*************************************************************************************************/ +lctrBigCtx_t *lctrFindBigBySyncHandle(uint16_t syncHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if ((pBigCtx->enabled) && + (pBigCtx->roleData.mst.pPerScanCtx == LCTR_GET_PER_SCAN_CTX(syncHandle))) + { + return pBigCtx; + } + } + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Check is current BIG synchronization in progress. + * + * \return TRUE if syncrhonizing in progres, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrIsBigSynchronizing(void) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if ((pBigCtx->enabled) && + (pBigCtx->state == LCTR_MST_BIG_STATE_SYNCING)) + { + return TRUE; + } + } + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a BIS context. + * + * \param pBigCtx Pointer to the BIG context. + * + * \return BIS context or NULL if at capacity. + */ +/*************************************************************************************************/ +lctrBisCtx_t *lctrAllocBisCtx(lctrBigCtx_t *pBigCtx) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBis; i++) + { + lctrBisCtx_t *pBisCtx = &pLctrBisTbl[i]; + + if (!pBisCtx->enabled) + { + memset(pBisCtx, 0, sizeof(lctrBisCtx_t)); + + /* State and context. */ + pBisCtx->enabled = TRUE; + pBisCtx->handle = LCTR_FIRST_BIS_HANDLE + i; + pBisCtx->pBigCtx = pBigCtx; + pBisCtx->bisNum = pBigCtx->numBis + 1; + + pBisCtx->path = LL_ISO_DATA_PATH_DISABLED; + + /* Parent context. */ + pBigCtx->pBisCtx[pBigCtx->numBis++] = pBisCtx; + + return pBisCtx; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup BIS context, clean BIG context if necessary for slave. + * + * \param pBisCtx BIS context to free. + */ +/*************************************************************************************************/ +void lctrCleanupBisCtx(lctrBisCtx_t *pBisCtx) +{ +} + +/*************************************************************************************************/ +/*! + * \brief Free a BIS context. + * + * \param pBisCtx BIS context to free. + */ +/*************************************************************************************************/ +void lctrFreeBisCtx(lctrBisCtx_t *pBisCtx) +{ + WSF_ASSERT(pBisCtx->enabled); + pBisCtx->enabled = FALSE; + + uint8_t *pPdu; + + /* Flush remaining packets. */ + switch (pBisCtx->pBigCtx->role) + { + case LL_ROLE_MASTER: + while ((pPdu = lctrBisDequeueRxDataPdu(pBisCtx, NULL)) != NULL) + { + lctrBisRxIsoDataPduFree(pPdu); + } + + lctrIsoalRxDataPathClear(&pBisCtx->roleData.mst.isoalRxCtx, pBisCtx->pBigCtx->framing); + break; + case LL_ROLE_SLAVE: + while (!WsfQueueEmpty(&pBisCtx->roleData.slv.txDataQ)) + { + lctrBisTxQueuePopCleanup(pBisCtx, 1); + } + + /* Free any IsoalTxPendQ */ + void *pIsoBuf; + uint8_t handlerId; + while ((pIsoBuf = WsfMsgDeq(&pBisCtx->roleData.slv.isoalTxCtx.pendingSduQ, &handlerId)) != NULL) + { + WsfMsgFree(pIsoBuf); + } + break; + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Find a BIS by handle. + * + * \param bisHandle BIS handle. + * + * \return BIS context or NULL if not found. + */ +/*************************************************************************************************/ +lctrBisCtx_t *lctrFindBisByHandle(uint16_t bisHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBis; i++) + { + lctrBisCtx_t *pBisCtx = &pLctrBisTbl[i]; + + if ((pBisCtx->enabled) && + (pBisCtx->handle == bisHandle)) + { + return pBisCtx; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available BIS contexts. + * + * \return Number of available BIS contexts. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumAvailBisCtx(void) +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pLctrRtCfg->maxBis; i++) + { + lctrBisCtx_t *pBisCtx = &pLctrBisTbl[i]; + + if (pBisCtx->enabled == FALSE) + { + count++; + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Compute new access address. + * + * \param seedAccAddr Seed access address. + * \param bisNum BIS number. + * + * \return New seed access address value. + */ +/*************************************************************************************************/ +uint32_t lctrComputeBisAccessAddr(uint32_t seedAccAddr, uint8_t bisNum) +{ + uint32_t accAddr = seedAccAddr; + uint16_t div; + uint32_t dw = 0; + uint8_t d0, d1, d2, d3, d4, d5, d6; + + d0 = d1 = d2 = d3 = d4 = d5 = d6 = 0; + + /* Diversifier = ((35 * n) + 42) MOD 128 */ + const uint16_t term = (35 * bisNum) + 42; + div = term - ((term >> 7) * 128); + + d0 = div & 1; + d1 = (div >> 1) & 1; + d2 = (div >> 2) & 1; + d3 = (div >> 3) & 1; + d4 = (div >> 4) & 1; + d5 = (div >> 5) & 1; + d6 = (div >> 6) & 1; + + /* DW = D0D0D0D0D0D0D1D6_D10D5D40D3D20_00000000_00000000b Note the digit after the letter is the index of the D. */ + dw = ((d0 << 31) | (d0 << 30) | (d0 << 29) | (d0 << 28) | (d0 << 27) | (d0 << 26) | (d1 << 25) | (d6 << 24) | \ + (d1 << 23) | (d5 << 21) | (d4 << 20) | (d3 << 18) | (d2 << 17)); + + /* SAA bit-wise XORed with DW */ + accAddr ^= dw; + + return accAddr; +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new BIS. + * + * \param pBisCtx BIS context. + * \param seedAccAddr Seed access address. + * \param baseCrcInit Base CRC Init. + * \param chMap Channel map. + * \param phy PHY. + */ +/*************************************************************************************************/ +void lctrSetupBisContext(lctrBisCtx_t *pBisCtx, uint32_t seedAccAddr, uint16_t baseCrcInit, uint64_t chMap, LlPhy_t phy) +{ + pBisCtx->chan.opType = (pBisCtx->pBigCtx->role == LL_ROLE_SLAVE) ? BB_BLE_OP_SLV_BIS_EVENT : BB_BLE_OP_MST_BIS_EVENT; + + uint32_t accAddr = lctrComputeBisAccessAddr(seedAccAddr, pBisCtx->bisNum); + + pBisCtx->chSelInfo.chanMask = chMap; + pBisCtx->chSelInfo.usedChSel = LL_CH_SEL_2; + pBisCtx->chSelInfo.chIdentifier = (accAddr >> 16) ^ (accAddr >> 0); + LmgrBuildRemapTable(&pBisCtx->chSelInfo); + + pBisCtx->chan.accAddr = accAddr; + pBisCtx->chan.crcInit = (baseCrcInit << 8) | pBisCtx->bisNum; + pBisCtx->chan.txPower = lmgrCb.advTxPwr; + pBisCtx->chan.txPhy = pBisCtx->chan.rxPhy = phy; + pBisCtx->chan.initTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; + pBisCtx->chan.tifsTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; + /* pBisCtx->chan.peerTxStableModIdx = FALSE; */ + +#if (LL_ENABLE_TESTER) + pBisCtx->chan.accAddrRx = pBisCtx->chan.accAddr ^ llTesterCb.dataAccessAddrRx; + pBisCtx->chan.accAddrTx = pBisCtx->chan.accAddr ^ llTesterCb.dataAccessAddrTx; + pBisCtx->chan.crcInitRx = pBisCtx->chan.crcInit ^ llTesterCb.dataCrcInitRx; + pBisCtx->chan.crcInitTx = pBisCtx->chan.crcInit ^ llTesterCb.dataCrcInitTx; +#endif + + if (pBisCtx->pBigCtx->encrypt) + { + pBisCtx->chan.enc.enaEncrypt = TRUE; + pBisCtx->chan.enc.enaDecrypt = TRUE; + pBisCtx->chan.enc.enaAuth = TRUE; + pBisCtx->chan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + + memcpy(pBisCtx->chan.enc.iv, pBisCtx->pBigCtx->giv, LL_IV_LEN); + pBisCtx->chan.enc.iv[0] ^= accAddr >> 0; + pBisCtx->chan.enc.iv[1] ^= accAddr >> 8; + pBisCtx->chan.enc.iv[2] ^= accAddr >> 16; + pBisCtx->chan.enc.iv[3] ^= accAddr >> 24; + + memcpy(pBisCtx->chan.enc.sk, pBisCtx->pBigCtx->bleData.chan.enc.sk, PAL_CRYPTO_LL_KEY_LEN); + + /* The directionBit shall be set to 1 for Broadcast Isochronous PDUs. */ + pBisCtx->chan.enc.dir = 1; + pBisCtx->chan.enc.type = PAL_BB_TYPE_BIS; + + lctrInitCipherBlkHdlr(&pBisCtx->chan.enc, pBisCtx->handle, 1); + } +} + +/*************************************************************************************************/ +/*! + * \brief Select all BIS channels and BIG Control channels. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrSelectBigChannels(lctrBigCtx_t *pBigCtx) +{ + /* Select BIS channels. */ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + pBisCtx->chan.chanIdx = LmgrSelectNextChannel(&pBisCtx->chSelInfo, pBigCtx->eventCounter, 0, TRUE); + } + + /* Select BIG Control channel. */ + pBigCtx->ctrChan.chanIdx = LmgrSelectNextChannel(&pBigCtx->ctrChSelInfo, pBigCtx->eventCounter, 0, TRUE); + + /* Setup BOD for next BIG Event. */ + pBigCtx->bleData.chan.chanIdx = pBigCtx->pBisCtx[0]->chan.chanIdx; + +} + +/*************************************************************************************************/ +/*! + * \brief Remap all BIS channels and BIG Control channels. + * + * \param pBigCtx BIG context. + * \param chanMap New channel map. + */ +/*************************************************************************************************/ +void lctrRemapBigChannels(lctrBigCtx_t *pBigCtx, uint64_t chanMap) +{ + /* Select BIS channels. */ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + pBisCtx->chSelInfo.chanMask = chanMap; + LmgrBuildRemapTable(&pBisCtx->chSelInfo); + } + + /* Select BIG Control channel. */ + pBigCtx->ctrChSelInfo.chanMask = chanMap; + LmgrBuildRemapTable(&pBigCtx->ctrChSelInfo); +} + +/*************************************************************************************************/ +/*! + * \brief Queue BIS ISO SDU onto Tx queue. + * + * \param pBisCtx BIS context. + * \param pIsoHdr ISO header. + * \param pIsoSdu ISO SDU buffer. + */ +/*************************************************************************************************/ +void lctrBisTxIsoPduQueue(lctrBisCtx_t *pBisCtx, lctrIsoHdr_t *pIsoHdr, uint8_t *pIsoSdu) +{ + lctrIsoTxBufDesc_t *pDesc; + + if ((pDesc = lctrAllocIsoTxBufDesc()) == NULL) + { + LL_TRACE_ERR1("Failed to allocate transmit buffer descriptor: bisHandle=%u", pIsoHdr->handle); + WsfMsgFree(pIsoSdu); + if (!pBisCtx->test.enabled) + { + uint16_t handle = pIsoHdr->handle; + uint16_t numSdu = 1; + + lmgrPersistCb.sendIsoCompCback(1, &handle, &numSdu); + } + lctrIsoSduTxIncAvailBuf(); + + lctrNotifyHostHwErrInd(LL_ERROR_CODE_MEM_CAP_EXCEEDED); + return; + } + + lctrBisFragmentIsoSdu(pBisCtx, pIsoHdr, pIsoSdu, pDesc); + WsfMsgEnq(&pBisCtx->roleData.slv.txDataQ, pIsoHdr->handle, (uint8_t *)pDesc); +} + +/*************************************************************************************************/ +/*! + * \brief Get top element in Tx queue. + * + * \param pBisCtx Connection context. + * \param burstIdx Burst index. + * \param descs Storage for BB descriptors. + * + * \return Number of BB descriptors. + */ +/*************************************************************************************************/ +uint8_t lctrBisTxQueuePeek(lctrBisCtx_t *pBisCtx, uint8_t burstIdx, PalBbBleTxBufDesc_t *descs) +{ + wsfHandlerId_t handlerId; + lctrIsoTxBufDesc_t *pDesc; + uint8_t descCnt = 0; + uint8_t sduCnt = 0; + + if (burstIdx > pBisCtx->pBigCtx->bn) + { + /* Advance to the pre-transmission PDU. */ + burstIdx += pBisCtx->pBigCtx->pto * pBisCtx->pBigCtx->bn; + } + + /* Do not remove from queue until burst completes. */ + while ((pDesc = WsfMsgNPeek(&pBisCtx->roleData.slv.txDataQ, sduCnt++, &handlerId)) != NULL) + { + if (pDesc->isoLen > 0) + { + unsigned int numFrag = LlMathDivideUint32RoundUp(pDesc->isoLen, pDesc->fragLen); + + if (burstIdx >= numFrag) + { + /* Advance to next SDU. */ + burstIdx -= numFrag; + continue; + } + + uint8_t fragCnt = burstIdx; + uint16_t fragOffs = pDesc->fragLen * fragCnt; + + if (fragOffs < pDesc->isoLen) + { + uint16_t fragSize = WSF_MIN(pDesc->isoLen - fragOffs, pDesc->fragLen); + + descs[0].len = pDesc->frag[fragCnt].hdrLen; + descs[0].pBuf = pDesc->frag[fragCnt].hdr; + descs[1].len = fragSize; + descs[1].pBuf = pDesc->pPduBuf + fragOffs; + descs[2].pBuf = NULL; + descCnt = 2; + if (pDesc->frag[fragCnt].trlLen) + { + descs[2].len = pDesc->frag[fragCnt].trlLen; + descs[2].pBuf = pDesc->frag[fragCnt].trl; + descCnt = 3; + } + + /* Exit loop. */ + break; + } + } + else + { + /* Zero length PDU. */ + descs[0].len = pDesc->frag[0].hdrLen; + descs[0].pBuf = pDesc->frag[0].hdr; + descs[1].pBuf = NULL; + descCnt = 1; + + /* Exit loop. */ + break; + } + } + + return descCnt; +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element from Tx queue. + * + * \param pBisCtx BIS context. + * \param numFrag Number of fragments to cleanup. + */ +/*************************************************************************************************/ +void lctrBisTxQueuePopCleanup(lctrBisCtx_t *pBisCtx, uint8_t numFrag) +{ + lctrIsoTxBufDesc_t *pDesc; + wsfHandlerId_t handlerId; + + while (numFrag-- && + ((pDesc = WsfMsgPeek(&pBisCtx->roleData.slv.txDataQ, &handlerId)) != NULL)) + { + pDesc->fragCnt++; + + if ((pDesc->fragLen * pDesc->fragCnt) >= pDesc->isoLen) /* last fragment */ + { + WsfMsgDeq(&pBisCtx->roleData.slv.txDataQ, &handlerId); + WsfMsgFree(pDesc->pIsoSdu); + lctrFreeIsoTxBufDesc(pDesc); + lctrIsoSduTxIncAvailBuf(); + + if (pBisCtx->path == LL_ISO_DATA_PATH_HCI) + { + /* ISO Test does not send Tx Complete notifications. */ + if (!pBisCtx->test.enabled) + { + pBisCtx->roleData.slv.numTxSduComp++; + } + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a Tx BIS Control PDU buffer. + * + * \param pduLen Control PDU length. + * + * \return BIS Control PDU buffer or NULL if out of memory. + */ +/*************************************************************************************************/ +uint8_t *lctrBigTxCtrlAlloc(uint8_t pduLen) +{ + uint8_t *pBuf; + + if ((pBuf = WsfBufAlloc(LCTR_Q_ELEM_LEN + + sizeof(uint32_t) /* ReTx data with padding */ + + LL_DATA_HDR_LEN + + sizeof(uint8_t) /* Opcode */ + + pduLen)) == NULL) + { + return NULL; + } + + /* Return pointer to start of header. */ + return pBuf + LCTR_Q_ELEM_LEN + sizeof(uint32_t); +} + +/*************************************************************************************************/ +/*! + * \brief Queue a BIS Control PDU for transmission. + * + * \param pBigCtx BIG context. + * \param pBuf BIS Control PDU buffer. + * \param numReTx Number of retransmissions. + */ +/*************************************************************************************************/ +void lctrBigTxCtrlQueue(lctrBigCtx_t *pBigCtx, uint8_t *pBuf, uint8_t numReTx) +{ + /* Recover start of buffer. */ + pBuf -= sizeof(uint32_t); + + /* First byte is the retransmission number. */ + pBuf[0] = numReTx; + + /* Recover start of queue element. */ + pBuf -= LCTR_Q_ELEM_LEN; + + WsfQueuePush(&pBigCtx->roleData.slv.txCtrlQ, pBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Get top element in Tx BIG control queue. + * + * \param pBigCtx BIG context. + * + * \return Control PDU buffer or NULL if none available. + */ +/*************************************************************************************************/ +uint8_t *lctrBigTxCtrlQueuePeek(lctrBigCtx_t *pBigCtx) +{ + uint8_t *pBuf; + + /* Queue peek. */ + if ((pBuf = pBigCtx->roleData.slv.txCtrlQ.pHead) != NULL) + { + /* Return pointer to start of header. */ + return pBuf + LCTR_Q_ELEM_LEN + sizeof(uint32_t); + } + + /* No more BIS Control PDUs. */ + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element in Tx BIG control queue if retransmissions completed. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrBigTxCtrlQueuePop(lctrBigCtx_t *pBigCtx) +{ + uint8_t *pBuf; + + /* Queue peek. */ + pBuf = pBigCtx->roleData.slv.txCtrlQ.pHead; + + if (pBuf) + { + /* Recover start buffer. */ + pBuf += LCTR_Q_ELEM_LEN; + + /* Decrease retransmission count. */ + pBuf[0]--; + + if (pBuf[0] == 0) + { + /* No more retransmissions; cleanup and skip to next BIS Control PDU. */ + lctrBigTxCtrlQueuePopCleanup(pBigCtx); + pBigCtx->bcp.cssn++; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element from Tx BIG control queue. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrBigTxCtrlQueuePopCleanup(lctrBigCtx_t *pBigCtx) +{ + uint8_t *pBuf = WsfQueueDeq(&pBigCtx->roleData.slv.txCtrlQ); + + if (pBuf) + { + WsfBufFree(pBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a receive ISO Data PDU buffer. + * + * \return Pointer to the start of the ISO Data PDU buffer. + */ +/*************************************************************************************************/ +uint8_t *lctrBisRxIsoDataPduAlloc(void) +{ + const uint32_t allocLen = HCI_ISO_DL_MAX_LEN + pLctrRtCfg->maxIsoSduLen + BB_DATA_PDU_TAILROOM; + + if (lmgrIsoCb.availRxBuf == 0) + { + /* Flow control Rx path. */ + return NULL; + } + + uint8_t *pPdu; + + /* Use LL_ISO_PDU_MAX_LEN to ensure use of data buffers located in the large pool. */ + if ((pPdu = (uint8_t*)WsfMsgAlloc(allocLen)) != NULL) + { + /* Return start of ISO Data PDU. */ + pPdu += LCTR_ISO_SDU_START_OFFSET; + + /* Do not claim buffer until committed. */ + /* lctrIsoDataRxDecAvailBuf(); */ + } + + return pPdu; +} + +/*************************************************************************************************/ +/*! + * \brief Dequeue a received ISO SDU buffer. + * + * \param pBisCtx BIS context. + * + * \return Pointer to the start of the ISO SDU. + * + * \note Returned pointer must be freed with WsfMsgFree(). + */ +/*************************************************************************************************/ +uint8_t *lctrBisRxIsoSduDeq(lctrBisCtx_t *pBisCtx) +{ + wsfHandlerId_t bisHandle; + + uint8_t *pSdu = WsfMsgDeq(&pBisCtx->roleData.mst.rxIsoSduQ, &bisHandle); + + return pSdu; +} + +/*************************************************************************************************/ +/*! + * \brief Enqueue a received ISO SDU buffer. + * + * \param pBisCtx BIS context. + * \param pSdu BIS Data SDU buffer. + */ +/*************************************************************************************************/ +void lctrBisRxIsoSduEnq(lctrBisCtx_t *pBisCtx, uint8_t *pSdu) +{ + WsfMsgEnq(&pBisCtx->roleData.mst.rxIsoSduQ, pBisCtx->handle, pSdu); + lctrIsoDataRxDecAvailBuf(); +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a receive ISO Data PDU buffer. + * + * \param pPdu Pointer to the start of the ISO Data PDU buffer. + */ +/*************************************************************************************************/ +void lctrBisRxIsoDataPduFree(uint8_t *pPdu) +{ + /* Recover start of buffer. */ + WsfMsgFree(pPdu - LCTR_ISO_SDU_START_OFFSET); +} + +/*************************************************************************************************/ +/*! + * \brief Enqueue a receive ISO Data PDU buffer. + * + * \param pBisCtx BIS context. + * \param pRxBuf Received PDU data buffer to queue. + * \param evtCtr Event counter when packet was received. + */ +/*************************************************************************************************/ +void lctrBisEnqueueRxDataPdu(lctrBisCtx_t *pBisCtx, uint8_t *pRxBuf, uint64_t evtCtr) +{ + WsfMsgEnq(&pBisCtx->roleData.mst.rxDataQ, (uint8_t)evtCtr, pRxBuf - LCTR_ISO_SDU_START_OFFSET); +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element from Tx queue. + * + * \param pBisCtx BIS context. + * \param pEvtCtrLsb Least significant byte of the event counter. + * + * \return Pointer to ISO Data PDU. + */ +/*************************************************************************************************/ +uint8_t *lctrBisDequeueRxDataPdu(lctrBisCtx_t *pBisCtx, uint8_t *pEvtCtrLsb) +{ + uint8_t *pBuf; + uint8_t temp8; + + if (pEvtCtrLsb == NULL) + { + pEvtCtrLsb = &temp8; + } + + if ((pBuf = WsfMsgDeq(&pBisCtx->roleData.mst.rxDataQ, pEvtCtrLsb)) == NULL) + { + return NULL; + } + + return pBuf + LCTR_ISO_SDU_START_OFFSET; +} + +/*************************************************************************************************/ +/*! + * \brief Enable BIS Tx test. + * + * \param pBisCtx BIS context. + * \param pldType Payload length type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrBisTxTest(lctrBisCtx_t *pBisCtx, uint8_t pldType) +{ + uint8_t status = LL_SUCCESS; + + if (pBisCtx->test.enabled || pBisCtx->test.term) + { + LL_TRACE_WARN0("Invalid ISO Test state, test mode already enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (lmgrIsoCb.availTxBuf == 0) + { + LL_TRACE_WARN0("Out of memory, no ISO Tx buffers available"); + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + + /* BIS Data PDU generation occurs ever SDU Interval in lctrSlvBigEndOp(). */ + + pBisCtx->test.enabled = TRUE; + pBisCtx->test.term = FALSE; + pBisCtx->test.util.framed.payloadCtr = 0; +#if (LL_ENABLE_TESTER) + pBisCtx->test.util.framed.payloadCtr = llTesterCb.isoTxTestNumInit; +#endif + pBisCtx->test.pldType = pldType; + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Enable BIS Rx test. + * + * \param pBisCtx BIS context. + * \param pldType Payload length type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrBisRxTest(lctrBisCtx_t *pBisCtx, uint8_t pldType) +{ + uint8_t status = LL_SUCCESS; + + if (pBisCtx->test.enabled || pBisCtx->test.term) + { + LL_TRACE_WARN0("Invalid ISO Test state, test mode already enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + pBisCtx->test.enabled = TRUE; + pBisCtx->test.term = FALSE; + pBisCtx->test.pendInit = TRUE; + pBisCtx->test.pldType = pldType; + memset(&pBisCtx->roleData.mst.stats, 0, sizeof(pBisCtx->roleData.mst.stats)); + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief BIS read ISO test counters. + * + * \param pBisCtx BIS context. + * \param pStats Pointer to the statistics block. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrBisReadTestCounters(lctrBisCtx_t *pBisCtx, LlIsoTestCtrs_t *pStats) +{ + if (pBisCtx->test.enabled == FALSE) + { + LL_TRACE_WARN0("Invalid ISO Test state, test mode must be enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + *pStats = pBisCtx->roleData.mst.stats; + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize connected isochronous memory resources. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + */ +/*************************************************************************************************/ +uint16_t LctrInitBisMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + uint8_t *pAvailMem = pFreeMem; + + /*** Advertising Set Context ***/ + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + LL_TRACE_INFO2(" RAM: %u x %u bytes -- BIS context", pLctrRtCfg->maxBis, sizeof(lctrBisCtx_t)); + + /* Allocate BIS context memory. */ + pLctrBisTbl = (lctrBisCtx_t *)pAvailMem; + pAvailMem += sizeof(lctrBisCtx_t) * pLctrRtCfg->maxBis; + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + LL_TRACE_INFO2(" RAM: %u x %u bytes -- BIG context", pLctrRtCfg->maxBig, sizeof(lctrBigCtx_t)); + + /* Allocate BIG context memory. */ + pLctrBigTbl = (lctrBigCtx_t *)pAvailMem; + pAvailMem += sizeof(lctrBigCtx_t) * pLctrRtCfg->maxBig; + + if (((uint32_t)(pAvailMem - pFreeMem)) > freeMemSize) + { + LL_TRACE_ERR2("LctrInitBisMem: failed to allocate BIG, need=%u available=%u", (pAvailMem - pFreeMem), freeMemSize); + WSF_ASSERT(FALSE); + return 0; + } + + lmgrPersistCb.bisCtxSize = sizeof(lctrBisCtx_t); + lmgrPersistCb.bigCtxSize = sizeof(lctrBigCtx_t); + + return (pAvailMem - pFreeMem); +} + +/*************************************************************************************************/ +/*! + * \brief BIS Tx Data PDU complete handler. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrNotifyIsoTxComplete(lctrBigCtx_t *pBigCtx) +{ + uint8_t numHandles = 0; + uint16_t handle[LL_MAX_BIS] = { 0 }; + uint16_t numSdu[LL_MAX_BIS] = { 0 }; + + /* Tally total transmitted SDUs. */ + for (unsigned int i = 0; i < pBigCtx->numBis; i++) + { + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[i]; + + if (pBisCtx->path == LL_ISO_DATA_PATH_HCI) + { + if (pBisCtx->roleData.slv.numTxSduComp) + { + handle[numHandles] = pBisCtx->handle; + numSdu[numHandles] = pBisCtx->roleData.slv.numTxSduComp; + pBisCtx->roleData.slv.numTxSduComp = 0; + numHandles++; + } + } + } + + if (numHandles) + { + /* Notify host completed SDUs. */ + lmgrPersistCb.sendIsoCompCback(numHandles, handle, numSdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief Calculate Group session key. + * + * \param pGSKD Group Session Key Diversifier. + * \param pBC Broadcast Code. + * \param pGSK Group Session Key result. + */ +/*************************************************************************************************/ +void lctrBisCalcGroupSessionKey(const uint8_t *pGSKD, const uint8_t *pBC, uint8_t *pGSK) +{ + static const uint8_t big1[PAL_CRYPTO_LL_KEY_LEN] = { 0x31, 0x47, 0x49, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t big2[4] = { 0x32, 0x47, 0x49, 0x42 }; + static const uint8_t big3[4] = { 0x33, 0x47, 0x49, 0x42 }; + uint8_t igltk[PAL_CRYPTO_LL_KEY_LEN]; + uint8_t gltk[PAL_CRYPTO_LL_KEY_LEN]; + uint8_t ik[PAL_CRYPTO_LL_KEY_LEN]; + + /* IGLTK = h7("BIG1", Broadcast_Code) */ + PalCryptoAesCmac(big1, igltk, pBC, 16); + + /* GLTK = h6(IGLTK, "BIG2") */ + PalCryptoAesCmac(igltk, gltk, big2, 4); + + /* GSK = h8(GLTK, GSKD, "BIG3") */ + PalCryptoAesCmac(pGSKD, ik, gltk, 16); + PalCryptoAesCmac(ik, pGSK, big3, 4); +} + +/*************************************************************************************************/ +/*! + * \brief Set the BIS data path. + * + * \param pBisCtx BIS context. + * \param dpDir Data path direction. + * \param dpId Data path ID. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrBisSetDataPath(lctrBisCtx_t *pBisCtx, LlIsoDataPathDir_t dpDir, LlIsoDataPath_t dpId) +{ + if (pBisCtx->path == dpId) + { + /* No change. */ + return LL_SUCCESS; + } + + /*** Stop current data path. ***/ + + switch (pBisCtx->path) + { + case LL_ISO_DATA_PATH_VS: + if (!lctrCodecHdlr.stop) + { + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + lctrCodecHdlr.stop(pBisCtx->handle); + break; + case LL_ISO_DATA_PATH_DISABLED: + case LL_ISO_DATA_PATH_HCI: + default: + /* No action required. */ + break; + } + + /*** Start new data path. ***/ + + pBisCtx->path = dpId; + + switch (dpId) + { + case LL_ISO_DATA_PATH_VS: + if (lctrCodecHdlr.start) + { + PalCodecSreamParam_t param = + { + .dir = (dpDir == LL_ISO_DATA_DIR_INPUT) ? PAL_CODEC_DIR_INPUT : PAL_CODEC_DIR_OUTPUT, + .chMask = PAL_CODEC_CH_LEFT_BIT | PAL_CODEC_CH_RIGHT_BIT, + .intervalUsec = pBisCtx->pBigCtx->isoInterUsec, + .pktCtr = (pBisCtx->pBigCtx->eventCounter + 1) * pBisCtx->pBigCtx->bn, + .rdyCback = lctrIsoSendCodecSdu + }; + + if (!lctrCodecHdlr.start(pBisCtx->handle, ¶m)) + { + LL_TRACE_WARN1("Failed to start the codec, dpId=%u", dpId); + pBisCtx->path = LL_ISO_DATA_PATH_DISABLED; + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + } + else + { + LL_TRACE_WARN1("Codec not found, dpId=%u", dpId); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + break; + case LL_ISO_DATA_PATH_DISABLED: + case LL_ISO_DATA_PATH_HCI: + /* No action required. */ + break; + default: + LL_TRACE_WARN1("Unknown Data Path, dpId=%u", dpId); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Calculate next subevent index values, using sequential packing. + * + * \param pBigCtx BIG context. + * \param pSeCtx Subevent context. + * \param numSePkts Total number of subevent packets. + * + * \return TRUE if more subevents pending, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrSlvBisCalcNextIdxSequential(lctrBigCtx_t *pBigCtx, lctrSeCtx_t *pSeCtx, uint8_t numSePkts) +{ + /* Burst loop. */ + + pSeCtx->burstIdx++; + + if (pSeCtx->burstIdx >= pBigCtx->bn) /* Last burst */ + { + pSeCtx->burstIdx = 0; + + /* Retransmission loop. */ + + pSeCtx->repIdx++; + + if (pSeCtx->repIdx >= pBigCtx->irc) /* Last retransmission */ + { + pSeCtx->repIdx = 0; + + if (numSePkts < pBigCtx->nse) + { + /* Pretransmission loop. */ + + pSeCtx->ptIdx++; + numSePkts++; + } + else + { + /* BIS loop. */ + + pSeCtx->bisEvtIdx++; + + if (pSeCtx->bisEvtIdx >= pBigCtx->numBis) /* Last BIS */ + { + /* Control SubEvent */ + return FALSE; + } + } + } + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Calculate next subevent index values, using interleaved packing. + * + * \param pBigCtx BIG context. + * \param pSeCtx Subevent context. + * \param numSePkts Total number of subevent packets. + * + * \return TRUE if more subevents pending, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrSlvBisCalcNextIdxInterleaved(lctrBigCtx_t *pBigCtx, lctrSeCtx_t *pSeCtx, uint8_t numSePkts) +{ + /* BIS loop. */ + + pSeCtx->bisEvtIdx++; + + if (pSeCtx->bisEvtIdx >= pBigCtx->numBis) /* Last BIS */ + { + pSeCtx->bisEvtIdx = 0; + + /* Burst loop. */ + + pSeCtx->burstIdx++; + + if (pSeCtx->burstIdx >= pBigCtx->bn) /* Last burst */ + { + pSeCtx->burstIdx = 0; + + /* Retransmission loop. */ + + pSeCtx->repIdx++; + + if (pSeCtx->repIdx >= pBigCtx->irc) /* Last retransmission */ + { + pSeCtx->repIdx = 0; + + /* Pretransmission loop. */ + + pSeCtx->ptIdx++; + numSePkts++; + + if (numSePkts > pBigCtx->nse) + { + /* Control SubEvent */ + return FALSE; + } + } + } + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_master.c new file mode 100644 index 00000000000..3b93cd38964 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_master.c @@ -0,0 +1,517 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller master operation builder implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_master.h" +#include "lctr_api_bis_master.h" +#include "lctr_int_iso.h" +#include "sch_api.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_timer.h" +#include + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief BIG message data. */ +lctrMstBigMsg_t *pLctrMstBigMsg; + +/*************************************************************************************************/ +/*! + * \brief BIS master message dispatcher. + * + * \param pMsg Pointer to message buffer. + */ +/*************************************************************************************************/ +static void lctrMstBigDisp(lctrMsgHdr_t *pMsg) +{ + pLctrMstBigMsg = (lctrMstBigMsg_t *)pMsg; + + if ((pMsg->dispId != LCTR_DISP_BCST) && + (pMsg->event != LCTR_MST_BIG_ACAD_BIG_INFO)) + { + lctrBigCtx_t *pBigCtx; + + if ((pBigCtx = lctrFindBigByHandle(pMsg->handle)) != NULL) + { + lctrMstBigExecuteSm(pBigCtx, pMsg->event); + } + } + else + { + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + if (pLctrBigTbl[i].enabled && (pLctrBigTbl[i].role == LL_ROLE_MASTER)) + { + pMsg->handle = pLctrBigTbl[i].handle; + lctrMstBigExecuteSm(&pLctrBigTbl[i], pMsg->event); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief BIS master reset handler. + */ +/*************************************************************************************************/ +static void lctrMstBisResetHandler(void) +{ + lctrBisDefaults(); +} + +/*************************************************************************************************/ +/*! + * \brief Periodic sync termination handler. + * + * \param syncHandle Periodic Sync handle. + */ +/*************************************************************************************************/ +static void lctrMstPerTermSync(uint16_t syncHandle) +{ + lctrBigCtx_t *pBigCtx; + + if ((pBigCtx = lctrFindBigBySyncHandle(syncHandle)) != NULL) + { + WSF_ASSERT(pBigCtx->role == LL_ROLE_MASTER); + + if (pBigCtx->roleData.mst.pPerScanCtx) + { + pBigCtx->roleData.mst.pPerScanCtx = NULL; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer controller resources for BIS master. + */ +/*************************************************************************************************/ +void LctrMstBisInit(void) +{ + /* Add reset handler. */ + lctrResetHdlrTbl[LCTR_DISP_BIG_SYNC] = lctrMstBisResetHandler; + + /* Add BIS slave message dispatcher. */ + lctrMsgDispTbl[LCTR_DISP_BIG_SYNC] = (LctrMsgDisp_t)lctrMstBigDisp; + + lctrBisDefaults(); + + /* Set supported features. */ + if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_1) + { + lmgrPersistCb.featuresDefault |= LL_FEAT_ISO_BROADCASTER; + } +} + +/*************************************************************************************************/ +/*! + * \brief BIG create sync + * + * \param pParam BIG Create Sync parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrMstBigCreateSync(LlBigCreateSync_t *pParam) +{ + lctrBigCtx_t *pBigCtx; + LctrAcadBigInfo_t *pBigInfo; + lctrPerScanCtx_t *pPerScanCtx; + + if (lctrIsBigSynchronizing()) + { + LL_TRACE_WARN0("LctrMstBigCreateSync: BIG synchronization in progress"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (lctrFindBigByHandle(pParam->bigHandle) != NULL) + { + LL_TRACE_WARN1("LctrMstBigCreateSync: bigHandle=%u already in use", pParam->bigHandle); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + pPerScanCtx = LCTR_GET_PER_SCAN_CTX(pParam->syncHandle); + + if ((pParam->syncHandle > LL_MAX_PER_SCAN) || + (pPerScanCtx->enabled == FALSE)) + { + LL_TRACE_WARN1("LctrMstBigCreateSync: syncHandle=%u not found", pParam->syncHandle); + return LL_ERROR_CODE_UNKNOWN_ADV_ID; + } + + if (lctrFindBigBySyncHandle(pParam->syncHandle) != NULL) + { + LL_TRACE_WARN1("LctrMstBigCreateSync: syncHandle=%u already in use", pParam->syncHandle); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + if (pPerScanCtx->acadParams[LCTR_ACAD_ID_BIG_INFO].hdr.len == 0) /* BIG Info received */ + { + LL_TRACE_WARN0("LctrMstBigCreateSync: synchronizer not ready; BIG Info not received"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + pBigInfo = &pPerScanCtx->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + + if (pParam->numBis > lctrGetNumAvailBisCtx()) + { + LL_TRACE_WARN0("LctrMstBigCreateSync: insufficient BIS context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + if (pParam->numBis > WSF_MIN(pBigInfo->numBis, LL_MAX_BIS)) + { + LL_TRACE_WARN2("LctrMstBigCreateSync: invalid value for numBis=%u, validRange=1..%u", pParam->numBis, WSF_MIN(pBigInfo->numBis, LL_MAX_BIS)); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + for (unsigned int i = 0; i < pParam->numBis; i++) + { + if ((pParam->bis[i] < LL_MIN_BIS) || + (pParam->bis[i] > LL_MAX_BIS)) + { + LL_TRACE_WARN2("BIS=%u at index=%u out of range", pParam->bis[i], i); + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + } + + if (pParam->encrypt != pBigInfo->encrypt) + { + LL_TRACE_WARN0("LctrMstBigCreateSync: encryption mode mismatch"); + return LL_ERROR_CODE_ENCRYPT_MODE_NOT_ACCEPTABLE; + } + + if ((pBigCtx = lctrAllocBigCtx(pParam->bigHandle)) == NULL) + { + LL_TRACE_WARN0("LctrMstBigCreateSync: insufficient BIG context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + pBigCtx->handle = pParam->bigHandle; + pPerScanCtx->termCback = lctrMstPerTermSync; + pBigCtx->roleData.mst.pPerScanCtx = pPerScanCtx; + pBigCtx->roleData.mst.mse = pParam->mse; + pBigCtx->roleData.mst.bigSyncTimeoutMs = pParam->bigSyncTimeout * 10; + pBigCtx->roleData.mst.numBisIdx = pParam->numBis; + memcpy(pBigCtx->roleData.mst.bisIdx, pParam->bis, pParam->numBis); + pBigCtx->encrypt = pParam->encrypt; + memcpy(pBigCtx->roleData.mst.bcstCode, pParam->bcstCode, LL_BC_LEN); + + /* Setup timer. */ + pBigCtx->roleData.mst.bigSyncTmr.handlerId = lmgrPersistCb.handlerId; + lctrMsgHdr_t *pMsg = (lctrMsgHdr_t *)&pBigCtx->roleData.mst.bigSyncTmr.msg; + pMsg->handle = pBigCtx->handle; + pMsg->dispId = LCTR_DISP_BIG_SYNC; + pMsg->event = LCTR_MST_BIG_INT_SYNC_TIMEOUT; + + if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pParam->bigHandle; + pMsg->dispId = LCTR_DISP_BIG_SYNC; + pMsg->event = LCTR_MST_BIG_API_CREATE_SYNC; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief BIG terminate sync + * + * \param bigHandle Used to identify the BIG. + */ +/*************************************************************************************************/ +void LctrMstBigTerminateSync(uint8_t bigHandle) +{ + lctrBigCtx_t *pBigCtx; + + if ((pBigCtx = lctrFindBigByHandle(bigHandle)) == NULL) + { + LL_TRACE_WARN1("LctrMstBigTerminateSync: unknown handle bigHandle=%u", bigHandle); + lctrNotifyHostBigTerminateComplete(LL_ERROR_CODE_UNKNOWN_ADV_ID, bigHandle); + return; + } + + if (pBigCtx->role != LL_ROLE_MASTER) + { + LL_TRACE_WARN0("LctrMstBigTerminateSync: invalid role"); + lctrNotifyHostBigTerminateComplete(LL_ERROR_CODE_CMD_DISALLOWED, bigHandle); + return; + } + + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = bigHandle; + pMsg->dispId = LCTR_DISP_BIG_SYNC; + pMsg->event = LCTR_MST_BIG_API_TERMINATE_SYNC; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Build BIG operation. + * + * \param pBigCtx BIG Context. + * \param pBigInfo BIG Info parameters from Broadcaster. + */ +/*************************************************************************************************/ +void lctrMstBigBuildOp(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo) +{ + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[0]; + + BbOpDesc_t * const pOp = &pBigCtx->bod; + BbBleData_t * const pBle = &pBigCtx->bleData; + BbBleMstBisEvent_t * const pBis = &pBle->op.mstBis; + + memset(pOp, 0, sizeof(BbOpDesc_t)); + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pBis, 0, sizeof(BbBleMstBisEvent_t)); + + /*** General Setup ***/ + + pOp->reschPolicy = BB_RESCH_FIXED_PREFERRED; + pOp->protId = BB_PROT_BLE; + pOp->prot.pBle = pBle; + pOp->endCback = lctrMstBigEndOp; + pOp->abortCback = lctrMstBigEndOp; + pOp->pCtx = pBigCtx; + + /*** BLE General Setup ***/ + + pBle->chan = pBisCtx->chan; + + /*** General setup ***/ + + pOp->minDurUsec = pBigInfo->subEvtInterUsec; + pOp->maxDurUsec = pBigInfo->subEvtInterUsec * pBigInfo->bn; + + /*** BIS setup ***/ + + /* pBis->rxSyncDelayUsec = 0; */ /* Deferred until BOD scheduled. */ + pBis->execCback = lctrMstBigBeginOp; + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + pBis->rxDataCback = lctrMstBisRxCompletion; + break; + + case LL_PACKING_SEQUENTIAL: + default: + pBis->rxDataCback = lctrMstBisRxCompletion; + break; + } + + /*** Commit operation ***/ + + /* Originate from peer's N-1 anchor point timing. */ + pBigCtx->roleData.mst.anchorPoint = pBigInfo->bigAnchorPoint; + pBigCtx->roleData.mst.rxSyncTime = pBigCtx->roleData.mst.anchorPoint - pBigCtx->isoInterUsec; + /* Expand receive window for initial synchronization due to resolution uncertainty. */ + pBigCtx->roleData.mst.extraWwUsec = (pBigInfo->bigOffsUnits == 0) ? 30 : 300; + uint32_t unsyncTimeUsec = 0; + + while (TRUE) + { + uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pBigCtx->roleData.mst.totalAcc); + /* TODO Limit to half the ISO Interval size */ + + pOp->dueUsec = pBigCtx->roleData.mst.anchorPoint - wwTotalUsec; + /* Multiply 2 for before and after BIG Anchor Point. */ + pBis->rxSyncDelayUsec = (wwTotalUsec << 1) + pBigCtx->roleData.mst.extraWwUsec; + + lctrSelectBigChannels(pBigCtx); + + if (SchInsertAtDueTime(pOp, NULL)) + { + break; + } + + LL_TRACE_WARN1("!!! BIG schedule conflict handle=%u", pBigCtx->handle); + + /* Advance to next interval. */ + pBigCtx->eventCounter += 1; + pBigCtx->roleData.mst.anchorPoint += pBigCtx->isoInterUsec; + unsyncTimeUsec += pBigCtx->isoInterUsec; + } + + LL_TRACE_INFO2(" >>> BIG synced, handle=%u, numBis=%u <<<", pBigCtx->handle, pBigCtx->numBis); + LL_TRACE_INFO3(" bn=%u, nse=%u, irc=%u", pBigCtx->bn, pBigCtx->nse, pBigCtx->irc); + LL_TRACE_INFO3(" pto=%u, framing=%u, packing=%u", pBigCtx->pto, pBigCtx->framing, pBigCtx->packing); + LL_TRACE_INFO1(" isoInterUsec=%u", pBigCtx->isoInterUsec); + LL_TRACE_INFO1(" bisSpaceUsec=%u", pBigCtx->bisSpaceUsec); + LL_TRACE_INFO1(" subInterUsec=%u", pBigCtx->subInterUsec); + LL_TRACE_INFO1(" eventCounter=%u", pBigCtx->eventCounter); + LL_TRACE_INFO1(" seedAccAddr=0x%08x", pBigCtx->seedAccAddr); + LL_TRACE_INFO1(" pBod=0x%08x", pOp); +} + +/*************************************************************************************************/ +/*! + * \brief Setup BIG context. + * + * \param pBigCtx BIG context. + * \param pBigInfo BIG Info. + */ +/*************************************************************************************************/ +void lctrMstSetupBigContext(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo) +{ + /* Packet */ + pBigCtx->maxPdu = pBigInfo->maxPdu; + pBigCtx->maxSdu = pBigInfo->maxSdu; + pBigCtx->seedAccAddr = pBigInfo->seedAccAddr; + pBigCtx->baseCrcInit = pBigInfo->baseCrcInit; + + /* Event */ + pBigCtx->bn = pBigInfo->bn; + pBigCtx->nse = pBigInfo->nse; + pBigCtx->irc = pBigInfo->irc; + pBigCtx->pto = pBigInfo->pto; + pBigCtx->framing = pBigInfo->framing; + pBigCtx->eventCounter = pBigInfo->bisPldCtr / pBigInfo->bn; /* TODO use optimized 64-bit divide */ + if (pBigInfo->bisSpaceUsec >= pBigInfo->subEvtInterUsec) + { + pBigCtx->packing = LL_PACKING_SEQUENTIAL; + } + else + { + pBigCtx->packing = LL_PACKING_INTERLEAVED; + } + + /* Control */ + pBigCtx->bcp.cssn = 0xFF; /* ensure reception of initial BIS Control PDU */ + + /* Radio */ + pBigCtx->phy = pBigInfo->phy; + + /* Encryption */ + pBigCtx->encrypt = pBigInfo->encrypt; + if (pBigCtx->encrypt) + { + memcpy(pBigCtx->giv, pBigInfo->giv, sizeof(pBigCtx->giv)); + memcpy(pBigCtx->gskd, pBigInfo->gskd, sizeof(pBigCtx->gskd)); + + /* Setup encryption parameters. */ + lctrBisCalcGroupSessionKey(pBigCtx->gskd, pBigCtx->roleData.mst.bcstCode, pBigCtx->bleData.chan.enc.sk); + } + + /* Timing */ + pBigCtx->isoInterUsec = pBigInfo->isoInter * 1250; + pBigCtx->bisSpaceUsec = pBigInfo->bisSpaceUsec; + pBigCtx->subInterUsec = pBigInfo->subEvtInterUsec; + /* pBigCtx->syncDelayUsec = N/A; */ + pBigCtx->sduInterUsec = pBigInfo->sduInterUsec; + pBigCtx->roleData.mst.totalAcc = lctrCalcTotalAccuracy(LL_MCA_20_PPM); +} + +/*************************************************************************************************/ +/*! + * \brief Setup BIG channelization parameters. + * + * \param pBigCtx BIG context. + * \param pBigInfo BIG Info. + */ +/*************************************************************************************************/ +void lctrMstSetupBigChannel(lctrBigCtx_t *pBigCtx, LctrAcadBigInfo_t *pBigInfo) +{ + pBigCtx->ctrChSelInfo.chanMask = pBigInfo->chanMap; + pBigCtx->ctrChSelInfo.usedChSel = LL_CH_SEL_2; + pBigCtx->ctrChSelInfo.chIdentifier = (uint16_t)(LL_BIG_CONTROL_ACCESS_ADDR >> 16) ^ + (uint16_t)(LL_BIG_CONTROL_ACCESS_ADDR >> 0); + LmgrBuildRemapTable(&pBigCtx->ctrChSelInfo); + + pBigCtx->ctrChan.opType = BB_BLE_OP_MST_BIS_EVENT; + pBigCtx->ctrChan.accAddr = lctrComputeBisAccessAddr(pBigInfo->seedAccAddr, 0); + pBigCtx->ctrChan.crcInit = (pBigCtx->baseCrcInit << 8) | 0; + pBigCtx->ctrChan.rxPhy = pBigCtx->phy; + +#if (LL_ENABLE_TESTER) + pBigCtx->ctrChan.accAddrRx = pBigCtx->ctrChan.accAddr ^ llTesterCb.dataAccessAddrRx; + pBigCtx->ctrChan.accAddrTx = pBigCtx->ctrChan.accAddr ^ llTesterCb.dataAccessAddrTx; + pBigCtx->ctrChan.crcInitRx = pBigCtx->ctrChan.crcInit ^ llTesterCb.dataCrcInitRx; + pBigCtx->ctrChan.crcInitTx = pBigCtx->ctrChan.crcInit ^ llTesterCb.dataCrcInitTx; +#endif + + if (pBigCtx->encrypt) + { + pBigCtx->ctrChan.enc.enaDecrypt = TRUE; + pBigCtx->ctrChan.enc.enaAuth = TRUE; + pBigCtx->ctrChan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + + memcpy(pBigCtx->ctrChan.enc.iv, pBigCtx->giv, LL_IV_LEN); + pBigCtx->ctrChan.enc.iv[0] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 0; + pBigCtx->ctrChan.enc.iv[1] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 8; + pBigCtx->ctrChan.enc.iv[2] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 16; + pBigCtx->ctrChan.enc.iv[3] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 24; + + memcpy(pBigCtx->ctrChan.enc.sk, pBigCtx->bleData.chan.enc.sk, PAL_CRYPTO_LL_KEY_LEN); + + /* The directionBit shall be set to 1 for Broadcast Isochronous PDUs. */ + pBigCtx->ctrChan.enc.dir = 1; + pBigCtx->ctrChan.enc.type = PAL_BB_TYPE_BIS; + + lctrInitCipherBlkHdlr(&pBigCtx->ctrChan.enc, LCTR_BIG_CTRL_ENC_ID(pBigCtx), 1); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send internal master BIG subsystem message. + * + * \param pBigCtx BIG context. + * \param event Master BIG event. + */ +/*************************************************************************************************/ +void lctrMstBigSendMsg(lctrBigCtx_t *pBigCtx, LctrMstBigMsg_t event) +{ + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(lctrMsgHdr_t))) != NULL) + { + pMsg->handle = pBigCtx->handle; + pMsg->dispId = LCTR_DISP_BIG_SYNC; + pMsg->event = event; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Set default values for BIS. + */ +/*************************************************************************************************/ +void lctrBisDefaults(void) +{ + memset(pLctrBisTbl, 0, sizeof(lctrBisCtx_t) * pLctrRtCfg->maxBis); + memset(pLctrBigTbl, 0, sizeof(lctrBigCtx_t) * pLctrRtCfg->maxBig); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_slave.c new file mode 100644 index 00000000000..1928a6384be --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_bis_slave.c @@ -0,0 +1,966 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller slave operation builder implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_slave.h" +#include "lctr_pdu_adv_ae.h" +#include "lctr_int_iso.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +extern uint8_t lctrChoosePreferredPhy(uint8_t val); + +/************************************************************************************************** + Local Function +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Compute the maximum PDU transmission time in microseconds. + * + * \param phy Transmission PHY. + * \param maxPdu Maximum PDU size. + * \param encrypt Encryption enabled. + * + * \return BIS Space in microseconds. + * + * \note This value includes preamble, access address, CRC and T_MSS. + */ +/*************************************************************************************************/ +static uint32_t lctrBisCalcMaxPduTimeUsec(uint8_t phy, uint8_t maxPdu, uint8_t encrypt) +{ + uint32_t duration; + + switch (phy) + { + case BB_PHY_BLE_1M: + default: + duration = LL_DATA_LEN_TO_TIME_1M(maxPdu, encrypt); + break; + case BB_PHY_BLE_2M: + duration = LL_DATA_LEN_TO_TIME_2M(maxPdu, encrypt); + break; + case BB_PHY_BLE_CODED: + duration = LL_DATA_LEN_TO_TIME_CODED_S8(maxPdu, encrypt); + break; + } + + return duration + LL_BLE_TMSS_US; +} + +/*************************************************************************************************/ +/*! + * \brief Setup BIG context. + * + * \param pBigCtx BIG context. + * \param pCreateBig Create BIG parameters. + */ +/*************************************************************************************************/ +static void lctrSlvSetupBigContext(lctrBigCtx_t *pBigCtx, LlCreateBig_t *pCreateBig) +{ + pBigCtx->role = LL_ROLE_SLAVE; + + pBigCtx->framing = pCreateBig->framing; + pBigCtx->packing = pCreateBig->packing; + + pBigCtx->phy = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCreateBig->phys)); + + pBigCtx->encrypt = pCreateBig->encrypt; + if (pBigCtx->encrypt) + { + /* Generate group parameters. */ + PalCryptoGenerateRandomNumber(pBigCtx->giv, LL_GIV_LEN); + PalCryptoGenerateRandomNumber(pBigCtx->gskd, LL_GSKD_LEN); + + /* Setup encryption parameters. */ + lctrBisCalcGroupSessionKey(pBigCtx->gskd, pCreateBig->bcstCode, pBigCtx->bleData.chan.enc.sk); + } + + /* Packet */ + pBigCtx->maxPdu = WSF_MIN(BB_DATA_PLD_MAX_LEN, pCreateBig->maxSdu); + pBigCtx->maxSdu = pCreateBig->maxSdu; + + /* Event */ + pBigCtx->bn = LlMathDivideUint32RoundUp(pCreateBig->maxSdu, pBigCtx->maxPdu); + pBigCtx->irc = pCreateBig->rtn + 1; + pBigCtx->pto = 0; + pBigCtx->nse = (pBigCtx->bn + pBigCtx->pto) * pBigCtx->irc; + + /* Timing */ + pBigCtx->sduInterUsec = pCreateBig->sduInterUsec; + pBigCtx->isoInterUsec = pCreateBig->sduInterUsec; + /* TODO consider MTL */ + /* TODO consider framing in BIS Space computation */ + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + { + pBigCtx->bisSpaceUsec = lctrBisCalcMaxPduTimeUsec(pBigCtx->phy, pBigCtx->maxPdu, pCreateBig->encrypt); + pBigCtx->subInterUsec = pBigCtx->bisSpaceUsec * pBigCtx->nse; + pBigCtx->syncDelayUsec = pCreateBig->numBis * pBigCtx->subInterUsec; + break; + } + + case LL_PACKING_SEQUENTIAL: + default: + { + pBigCtx->subInterUsec = lctrBisCalcMaxPduTimeUsec(pBigCtx->phy, pBigCtx->maxPdu, pCreateBig->encrypt); + pBigCtx->bisSpaceUsec = pBigCtx->subInterUsec * pBigCtx->nse; + pBigCtx->syncDelayUsec = pCreateBig->numBis * pBigCtx->bisSpaceUsec; + break; + } + } + + /* Ensure successful divide. */ + if (pBigCtx->bn || pBigCtx->sduInterUsec) + { + pBigCtx->transLatUsec = pBigCtx->syncDelayUsec + + pBigCtx->pto * (pBigCtx->nse / pBigCtx->bn - pBigCtx->irc) * pBigCtx->isoInterUsec + + ((pBigCtx->isoInterUsec / pBigCtx->sduInterUsec) - 1) * pBigCtx->sduInterUsec; + } + else + { + LL_TRACE_ERR0("Invalid BN or sduInterUsec value"); + pBigCtx->transLatUsec = LL_ISO_TRANSPORT_LAT_MIN; + } +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new BIG with test command. + * + * \param pBigCtx BIG context. + * \param pCreateBigTest Create BIG test parameters. + */ +/*************************************************************************************************/ +static void lctrSlvSetupBigTestContext(lctrBigCtx_t *pBigCtx, LlCreateBigTest_t *pCreateBigTest) +{ + pBigCtx->role = LL_ROLE_SLAVE; + + pBigCtx->framing = pCreateBigTest->framing; + pBigCtx->packing = pCreateBigTest->packing; + + pBigCtx->phy = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCreateBigTest->phys)); + + pBigCtx->encrypt = pCreateBigTest->encrypt; + if (pBigCtx->encrypt) + { + /* Generate group parameters. */ + PalCryptoGenerateRandomNumber(pBigCtx->giv, LL_GIV_LEN); + PalCryptoGenerateRandomNumber(pBigCtx->gskd, LL_GSKD_LEN); + + /* Setup encryption parameters. */ + lctrBisCalcGroupSessionKey(pBigCtx->gskd, pCreateBigTest->bcstCode, pBigCtx->bleData.chan.enc.sk); + } + + pBigCtx->maxPdu = pCreateBigTest->maxPdu; + pBigCtx->maxSdu = pCreateBigTest->maxSdu; + pBigCtx->sduInterUsec = pCreateBigTest->sduInterUsec; + pBigCtx->isoInterUsec = LCTR_ISO_INT_TO_US(pCreateBigTest->isoInter); + pBigCtx->bn = pCreateBigTest->bn; + pBigCtx->irc = pCreateBigTest->irc; + pBigCtx->pto = pCreateBigTest->pto; + pBigCtx->nse = (pBigCtx->bn + pBigCtx->pto) * pBigCtx->irc; + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + { + pBigCtx->bisSpaceUsec = lctrBisCalcMaxPduTimeUsec(pBigCtx->phy, pBigCtx->maxPdu, pCreateBigTest->encrypt); + pBigCtx->subInterUsec = pBigCtx->bisSpaceUsec * pBigCtx->nse; + pBigCtx->syncDelayUsec = pCreateBigTest->numBis * pBigCtx->subInterUsec; + break; + } + + case LL_PACKING_SEQUENTIAL: + default: + { + pBigCtx->subInterUsec = lctrBisCalcMaxPduTimeUsec(pBigCtx->phy, pBigCtx->maxPdu, pCreateBigTest->encrypt); + pBigCtx->bisSpaceUsec = pBigCtx->subInterUsec * pBigCtx->nse; + pBigCtx->syncDelayUsec = pCreateBigTest->numBis * pBigCtx->bisSpaceUsec; + break; + } + } + + /* Ensure successful divide. */ + if (pBigCtx->bn || pBigCtx->sduInterUsec) + { + pBigCtx->transLatUsec = pBigCtx->syncDelayUsec + + pBigCtx->pto * (pBigCtx->nse / pBigCtx->bn - pBigCtx->irc) * pBigCtx->isoInterUsec + + ((pBigCtx->isoInterUsec / pBigCtx->sduInterUsec) - 1) * pBigCtx->sduInterUsec; + } + else + { + LL_TRACE_ERR0("Invalid BN or sduInterUsec value"); + pBigCtx->transLatUsec = LL_ISO_TRANSPORT_LAT_MIN; + } +} + +/*************************************************************************************************/ +/*! + * \brief Setup BIG channelization parameters. + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +static void lctrSlvSetupBigChannel(lctrBigCtx_t *pBigCtx) +{ + pBigCtx->seedAccAddr = lctrComputeSeedAccessAddr(); + pBigCtx->baseCrcInit = lctrComputeCrcInit() >> 8; + + pBigCtx->ctrChSelInfo.chanMask = lmgrCb.chanClass; + pBigCtx->ctrChSelInfo.usedChSel = LL_CH_SEL_2; + pBigCtx->ctrChSelInfo.chIdentifier = (uint16_t)(LL_BIG_CONTROL_ACCESS_ADDR >> 16) ^ + (uint16_t)(LL_BIG_CONTROL_ACCESS_ADDR >> 0); + LmgrBuildRemapTable(&pBigCtx->ctrChSelInfo); + + pBigCtx->ctrChan.opType = BB_BLE_OP_SLV_BIS_EVENT; + pBigCtx->ctrChan.accAddr = lctrComputeBisAccessAddr(pBigCtx->seedAccAddr, 0); + + pBigCtx->ctrChan.crcInit = (pBigCtx->baseCrcInit << 8) | 0; + pBigCtx->ctrChan.txPower = lmgrCb.advTxPwr; + pBigCtx->ctrChan.txPhy = pBigCtx->phy; + pBigCtx->ctrChan.initTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; + pBigCtx->ctrChan.tifsTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; + /* pBigCtx->ctrChan.peerTxStableModIdx = FALSE; */ + +#if (LL_ENABLE_TESTER) + pBigCtx->ctrChan.accAddrRx = pBigCtx->ctrChan.accAddr ^ llTesterCb.dataAccessAddrRx; + pBigCtx->ctrChan.accAddrTx = pBigCtx->ctrChan.accAddr ^ llTesterCb.dataAccessAddrTx; + pBigCtx->ctrChan.crcInitRx = pBigCtx->ctrChan.crcInit ^ llTesterCb.dataCrcInitRx; + pBigCtx->ctrChan.crcInitTx = pBigCtx->ctrChan.crcInit ^ llTesterCb.dataCrcInitTx; +#endif + + if (pBigCtx->encrypt) + { + pBigCtx->ctrChan.enc.enaEncrypt = TRUE; + pBigCtx->ctrChan.enc.enaAuth = TRUE; + pBigCtx->ctrChan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + + memcpy(pBigCtx->ctrChan.enc.iv, pBigCtx->giv, LL_IV_LEN); + pBigCtx->ctrChan.enc.iv[0] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 0; + pBigCtx->ctrChan.enc.iv[1] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 8; + pBigCtx->ctrChan.enc.iv[2] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 16; + pBigCtx->ctrChan.enc.iv[3] ^= LL_BIG_CONTROL_ACCESS_ADDR >> 24; + + memcpy(pBigCtx->ctrChan.enc.sk, pBigCtx->bleData.chan.enc.sk, PAL_CRYPTO_LL_KEY_LEN); + + /* The directionBit shall be set to 1 for Broadcast Isochronous PDUs. */ + pBigCtx->ctrChan.enc.dir = 1; + pBigCtx->ctrChan.enc.type = PAL_BB_TYPE_BIS; + + lctrInitCipherBlkHdlr(&pBigCtx->ctrChan.enc, LCTR_BIG_CTRL_ENC_ID(pBigCtx), 1); + } +} + +/*************************************************************************************************/ +/*! + * \brief BIS slave reset handler. + */ +/*************************************************************************************************/ +static void lctrSlvBisResetHandler(void) +{ + lctrBisDefaults(); +} + +/*************************************************************************************************/ +/*! + * \brief BIG slave message dispatcher. + * + * \param pMsg Pointer to message buffer. + */ +/*************************************************************************************************/ +static void lctrSlvBigDisp(LctrSlvBigMsg_t *pMsg) +{ + if (pMsg->hdr.dispId != LCTR_DISP_BCST) + { + lctrBigCtx_t *pBigCtx; + + if ((pBigCtx = lctrFindBigByHandle(pMsg->hdr.handle)) != NULL) + { + lctrSlvBigExecuteSm(pBigCtx, pMsg->hdr.event); + } + } + else + { + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + if (pLctrBigTbl[i].enabled && (pLctrBigTbl[i].role == LL_ROLE_SLAVE)) + { + pMsg->hdr.handle = pLctrBigTbl[i].handle; + lctrSlvBigExecuteSm(&pLctrBigTbl[i], pMsg->hdr.event); + } + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Action function for ACAD BIG created. + * + * \param advHandle Advertising handle + */ +/*************************************************************************************************/ +static void lctrSlvBisAcadBigCreated(uint8_t advHandle) +{ + LctrAcadBigInfo_t *pBigInfo; + lctrAdvSet_t *pAdvSet = lctrFindAdvSet(advHandle); + lctrBigCtx_t *pBigCtx = lctrFindBigByHandle(pLctrAcadSlvMsg->bigCreated.bigHandle); + WSF_ASSERT(pBigCtx); + WSF_ASSERT(pAdvSet); + + pBigInfo = &pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + + /* A new BigInfo cannot replace a currently running one. */ + WSF_ASSERT(pBigInfo->hdr.state != LCTR_ACAD_STATE_ENABLED); + + if (pBigCtx->encrypt) + { + pBigInfo->hdr.len = LL_ACAD_BIG_INFO_ENCRPT_LEN; + memcpy(pBigInfo->giv, pBigCtx->giv, LL_GIV_LEN); + memcpy(pBigInfo->gskd, pBigCtx->gskd, LL_GSKD_LEN); + } + else + { + pBigInfo->hdr.len = LL_ACAD_BIG_INFO_UNENCRPT_LEN; + } + + pBigInfo->hdr.state = LCTR_ACAD_STATE_ENABLED; + + /* pBigInfo->bigOffs = 0; */ /* deferred until timing values are known */ + /* pBigInfo->bigOffsUnits = 0; */ /* deferred until timing values are known */ + pBigInfo->isoInter = LL_MATH_DIV_1250(pBigCtx->isoInterUsec); + pBigInfo->numBis = pBigCtx->numBis; + pBigInfo->nse = pBigCtx->nse; + pBigInfo->bn = pBigCtx->bn; + pBigInfo->subEvtInterUsec = pBigCtx->subInterUsec; + pBigInfo->pto = pBigCtx->pto; + pBigInfo->bisSpaceUsec = pBigCtx->bisSpaceUsec; + pBigInfo->irc = pBigCtx->irc; + pBigInfo->maxPdu = pBigCtx->maxPdu; + pBigInfo->seedAccAddr = pBigCtx->seedAccAddr; + pBigInfo->sduInterUsec = pBigCtx->sduInterUsec; + pBigInfo->maxSdu = pBigCtx->maxSdu; + pBigInfo->baseCrcInit = pBigCtx->baseCrcInit; + pBigInfo->chanMap = pBigCtx->ctrChSelInfo.chanMask; + pBigInfo->phy = pBigCtx->phy; + pBigInfo->bisPldCtr = pBigCtx->eventCounter * pBigCtx->bn; + pBigInfo->framing = pBigCtx->framing; + pBigInfo->encrypt = pBigCtx->encrypt; +} + +/*************************************************************************************************/ +/*! + * \brief Action function for ACAD BIG created. + * + * \param advHandle Advertising handle + */ +/*************************************************************************************************/ +static void lctrSlvBisAcadBigTerminated(uint8_t advHandle) +{ + lctrAdvSet_t *pAdvSet = lctrFindAdvSet(advHandle); + WSF_ASSERT(pAdvSet) + + lctrSlvAcadDisable(&pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO]); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for ACAD BIG created. + * + * \param advHandle Advertising handle + */ +/*************************************************************************************************/ +static void lctrSlvBisRemoveAdvSet(uint8_t advHandle) +{ + lctrAdvSet_t *pAdvSet = lctrFindAdvSet(advHandle); + + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if ((pBigCtx->role == LL_ROLE_SLAVE) && + (pBigCtx->roleData.slv.pAdvSet == pAdvSet)) + { + pBigCtx->roleData.slv.pAdvSet = NULL; + break; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Get reference time (due time) of the next BIG. + * + * \param rmHandle RM handle. + * \param pDurUsec Pointer to duration of the connection BOD. + * + * \return Due time in microseconds of the connection handle. + */ +/*************************************************************************************************/ +static uint32_t lctrGetBigRefTime(uint8_t rmHandle, uint32_t *pDurUsec) +{ + uint32_t refTime = 0; + lctrBigCtx_t *pBigCtx = LCTR_RM_HANDLE_TO_BIG(rmHandle); + + if (pBigCtx->enabled) + { + WSF_ASSERT(pBigCtx->bleData.chan.opType == BB_BLE_OP_SLV_BIS_EVENT); + + refTime = pBigCtx->bod.dueUsec; + + if (pDurUsec) + { + *pDurUsec = pBigCtx->bod.minDurUsec; + } + } + + return refTime; +} + +/*************************************************************************************************/ +/*! + * \brief Host channel class update handler for CIS master. + * + * \param chanMap Updated channel map. + * + * \return Status code. + */ +/*************************************************************************************************/ +static uint8_t lctrMstBigChClassUpdate(uint64_t chanMap) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxBig; i++) + { + lctrBigCtx_t *pBigCtx = &pLctrBigTbl[i]; + + if (pBigCtx->enabled && (pBigCtx->role == LL_ROLE_SLAVE)) + { + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(lctrMsgHdr_t))) != NULL) + { + pMsg->handle = pBigCtx->handle; + pMsg->dispId = LCTR_DISP_BIG_BCST; + pMsg->event = LCTR_SLV_BIG_MSG_CH_MAP_UPD; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + else + { + LL_TRACE_ERR0("lctrMstBigChClassUpdate: out of message buffers"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + } + + return LL_SUCCESS; +} + +/************************************************************************************************** + External Function +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer controller resources for BIS slave. + */ +/*************************************************************************************************/ +void LctrSlvBisInit(void) +{ + /* Add reset handler. */ + lctrResetHdlrTbl[LCTR_DISP_BIG_BCST] = lctrSlvBisResetHandler; + + /* Add BIS slave message dispatcher. */ + lctrMsgDispTbl[LCTR_DISP_BIG_BCST] = (LctrMsgDisp_t)lctrSlvBigDisp; + + lctrRegisterChClassHandler(lctrMstBigChClassUpdate); + + lctrBisDefaults(); + + /* Set supported features. */ + if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_1) + { + lmgrPersistCb.featuresDefault |= LL_FEAT_ISO_BROADCASTER; + } +} + +/*************************************************************************************************/ +/*! + * \brief BIG Create Sync. + * + * \param pCreateBig BIG create sync parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSlvBisCreateBig(LlCreateBig_t *pCreateBig) +{ + lctrBigCtx_t *pBigCtx; + + if (pCreateBig->numBis > pLctrRtCfg->maxBis) + { + LL_TRACE_WARN0("LctrSlvBisCreateBig: exceeds maximum allowed BIS context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + if (pCreateBig->numBis > lctrGetNumAvailBisCtx()) + { + LL_TRACE_WARN0("LctrSlvBisCreateBig: insufficient BIS context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + if ((pBigCtx = lctrFindBigByHandle(pCreateBig->bigHandle)) != NULL) + { + LL_TRACE_WARN1("LctrSlvBisCreateBig: bigHandle=%u already in use", pCreateBig->bigHandle); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + else + { + if (lctrBigIsPerAdvUsed(pCreateBig->advHandle) == TRUE) + { + LL_TRACE_WARN1("LctrSlvBisCreateBig: advHandle=%u not available", pCreateBig->advHandle); + return LL_ERROR_CODE_UNKNOWN_ADV_ID; + } + + if ((pBigCtx = lctrAllocBigCtx(pCreateBig->bigHandle)) == NULL) + { + LL_TRACE_WARN0("LctrSlvBisCreateBig: insufficient BIG context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + } + + lctrSlvSetupBigContext(pBigCtx, pCreateBig); + lctrSlvSetupBigChannel(pBigCtx); + + if (LlMathDivideUint32RoundUp(pBigCtx->maxSdu, pBigCtx->maxPdu) > LL_MAX_FRAG) + { + LL_TRACE_WARN1("LctrSlvBisCreateBig: exceeds maximum fragments max=%u", LL_MAX_FRAG); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + for (unsigned int i = 0; i < pCreateBig->numBis; i++) + { + lctrBisCtx_t *pBisCtx; + + pBisCtx = lctrAllocBisCtx(pBigCtx); + + if (pBisCtx) + { + lctrSetupBisContext(pBisCtx, pBigCtx->seedAccAddr, pBigCtx->baseCrcInit, lmgrCb.chanClass, pBigCtx->phy); + } + else + { + lctrFreeBigCtx(pBigCtx); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + } + + /* Assign function pointer for ACAD BIG. */ + lctrAdvSet_t *pAdvSet = lctrFindAdvSet(pCreateBig->advHandle); + if (pAdvSet) + { + pBigCtx->roleData.slv.pAdvSet = pAdvSet; + pAdvSet->bigCreated = &lctrSlvBisAcadBigCreated; + pAdvSet->bigTerminated = &lctrSlvBisAcadBigTerminated; + pAdvSet->removeCback = lctrSlvBisRemoveAdvSet; + } + + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pCreateBig->bigHandle; + pMsg->dispId = LCTR_DISP_BIG_BCST; + pMsg->event = LCTR_SLV_BIG_MSG_CREATE_BIG; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Create BIG test command. + * + * \param pCreateBigTest Create BIG test parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSlvBisCreateBigTest(LlCreateBigTest_t *pCreateBigTest) +{ + lctrBigCtx_t *pBigCtx; + + if (pCreateBigTest->numBis > lctrGetNumAvailBisCtx()) + { + LL_TRACE_WARN0("LctrSlvBisCreateBigTest: insufficient BIS context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + if ((pBigCtx = lctrFindBigByHandle(pCreateBigTest->bigHandle)) != NULL) + { + LL_TRACE_WARN1("LctrSlvBisCreateBigTest: bigHandle=%u already in use", pCreateBigTest->bigHandle); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + else + { + if (lctrBigIsPerAdvUsed(pCreateBigTest->advHandle) == TRUE) + { + LL_TRACE_WARN1("LctrSlvBisCreateBigTest: advHandle=%u not available", pCreateBigTest->advHandle); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + if ((pBigCtx = lctrAllocBigCtx(pCreateBigTest->bigHandle)) == NULL) + { + LL_TRACE_WARN0("LctrSlvBisCreateBigTest: insufficient BIG context"); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + } + + lctrSlvSetupBigTestContext(pBigCtx, pCreateBigTest); + lctrSlvSetupBigChannel(pBigCtx); + + if (LlMathDivideUint32RoundUp(pBigCtx->maxSdu, pBigCtx->maxPdu) > LL_MAX_FRAG) + { + LL_TRACE_WARN1("LctrSlvBisCreateBig: exceeds maximum fragments max=%u", LL_MAX_FRAG); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + for (unsigned int i = 0; i < pCreateBigTest->numBis; i++) + { + lctrBisCtx_t *pBisCtx; + + pBisCtx = lctrAllocBisCtx(pBigCtx); + + if (pBisCtx) + { + lctrSetupBisContext(pBisCtx, pBigCtx->seedAccAddr, pBigCtx->baseCrcInit, lmgrCb.chanClass, pBigCtx->phy); + } + else + { + lctrFreeBigCtx(pBigCtx); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + } + + /* Enable BIG Info ACAD. */ + lctrAdvSet_t *pAdvSet = lctrFindAdvSet(pCreateBigTest->advHandle); + if (pAdvSet) + { + pBigCtx->roleData.slv.pAdvSet = pAdvSet; + pAdvSet->bigCreated = lctrSlvBisAcadBigCreated; + pAdvSet->bigTerminated = lctrSlvBisAcadBigTerminated; + pAdvSet->removeCback = lctrSlvBisRemoveAdvSet; + } + + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pCreateBigTest->bigHandle; + pMsg->dispId = LCTR_DISP_BIG_BCST; + pMsg->event = LCTR_SLV_BIG_MSG_CREATE_BIG; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Terminate BIG. + * + * \param bigHandle BIG handle. + * \param reason Termination reason. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSlvBisTerminateBig(uint8_t bigHandle, uint8_t reason) +{ + lctrBigCtx_t *pBigCtx; + + if ((pBigCtx = lctrFindBigByHandle(bigHandle)) == NULL) + { + LL_TRACE_WARN1("LctrSlvBisTerminateBig: invalid BIG handle=%u", bigHandle); + return LL_ERROR_CODE_UNKNOWN_ADV_ID; + } + + if (pBigCtx->role != LL_ROLE_SLAVE) + { + LL_TRACE_WARN0("LctrSlvBisTerminateBig: invalid role"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (pBigCtx->state != LCTR_SLV_BIG_STATE_ENABLED) + { + LL_TRACE_WARN0("LctrSlvBisTerminateBig: invalid state"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + /* Store reason code. */ + pBigCtx->bcp.term.reason = reason; + + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = bigHandle; + pMsg->dispId = LCTR_DISP_BIG_BCST; + pMsg->event = LCTR_SLV_BIG_MSG_TERMINATE_BIG; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of Create BIG complete event + * + * \param pBigCtx BIG context. + * \param status Status. + */ +/*************************************************************************************************/ +void lctrNotifyHostCreateBigComplete(lctrBigCtx_t *pBigCtx, uint8_t status) +{ + LlCreateBigCnf_t evt; + + /* Clear not required; all values are written. */ + /* memset(&evt, 0, sizeof(LlCreateBigCnf_t)); */ + + evt.hdr.param = pBigCtx->handle; + evt.hdr.event = LL_CREATE_BIG_CNF; + evt.hdr.status = status; + + evt.status = status; + evt.bigHandle = pBigCtx->handle; + + if (evt.status == LL_SUCCESS) + { + evt.syncDelayUsec = pBigCtx->syncDelayUsec; + evt.transLatUsec = pBigCtx->transLatUsec; + evt.phy = pBigCtx->phy; + evt.nse = pBigCtx->nse; + evt.bn = pBigCtx->bn; + evt.pto = pBigCtx->pto; + evt.irc = pBigCtx->irc; + evt.maxPdu = pBigCtx->maxPdu; + evt.isoInterval = LL_MATH_DIV_1250(pBigCtx->isoInterUsec); + evt.numBis = pBigCtx->numBis; + + for (unsigned int i = 0; i < evt.numBis; i++) + { + evt.bisHandle[i] = pBigCtx->pBisCtx[i]->handle; + } + } + + LL_TRACE_INFO2("### LlEvent ### LL_CREATE_BIG_CNF, bigHandle=%u, status=%u", pBigCtx->handle, status); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of Create BIG complete event + * + * \param pBigCtx BIG context. + */ +/*************************************************************************************************/ +void lctrNotifyHostTerminateBigComplete(lctrBigCtx_t *pBigCtx) +{ + LlTerminateBigInd_t evt; + + /* Clear not required; all values are written. */ + /* memset(&evt, 0, sizeof(LlTerminateBigInd_t)); */ + + evt.hdr.param = pBigCtx->handle; + evt.hdr.event = LL_TERM_BIG_IND; + evt.hdr.status = LL_SUCCESS; + + evt.bigHandle = pBigCtx->handle; + evt.reason = pBigCtx->bcp.term.reason; + + LL_TRACE_INFO2("### LlEvent ### LL_TERM_BIG_IND, bigHandle=%u, reason=%u", pBigCtx->handle, pBigCtx->bcp.term.reason); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Send internal slave BIG subsystem message. + * + * \param pBigCtx BIG context. + * \param event Slave BIS event. + */ +/*************************************************************************************************/ +void lctrSlvBigSendMsg(lctrBigCtx_t *pBigCtx, uint8_t event) +{ + lctrMsgHdr_t *pMsg; + + if ((pMsg = WsfMsgAlloc(sizeof(lctrMsgHdr_t))) != NULL) + { + pMsg->handle = pBigCtx->handle; + pMsg->dispId = LCTR_DISP_BIG_BCST; + pMsg->event = event; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Send internal slave BIS ACAD subsystem message. + * + * \param pBigCtx BIG context. + * \param event Slave BIS event. + */ +/*************************************************************************************************/ +void lctrSlvBigSendAcadMsg(lctrBigCtx_t *pBigCtx, uint8_t event) +{ + if (!pBigCtx->roleData.slv.pAdvSet) + { + return; + } + + lctrBigCreated_t *pMsg; + + if ((pMsg = (lctrBigCreated_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = pBigCtx->roleData.slv.pAdvSet->handle; + pMsg->hdr.dispId = LCTR_DISP_ACAD; + pMsg->hdr.event = event; + pMsg->bigHandle = pBigCtx->handle; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } +} + +/*************************************************************************************************/ +/*! + * \brief Build BIG operation. + * + * \param pBigCtx BIG context. + * + * \return Error status code. + */ +/*************************************************************************************************/ +uint8_t lctrSlvBigBuildOp(lctrBigCtx_t *pBigCtx) +{ + lctrBisCtx_t * const pBisCtx = pBigCtx->pBisCtx[0]; + + BbOpDesc_t * const pOp = &pBigCtx->bod; + BbBleData_t * const pBle = &pBigCtx->bleData; + BbBleSlvBisEvent_t * const pBis = &pBle->op.slvBis; + + memset(pOp, 0, sizeof(BbOpDesc_t)); + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pBis, 0, sizeof(BbBleSlvBisEvent_t)); + + /*** General Setup ***/ + + pOp->reschPolicy = BB_RESCH_FIXED_PREFERRED; + pOp->protId = BB_PROT_BLE; + pOp->prot.pBle = pBle; + pOp->endCback = lctrSlvBigEndOp; + pOp->abortCback = lctrSlvBigAbortOp; + pOp->pCtx = pBigCtx; + + /*** BLE General Setup ***/ + + pBle->chan = pBisCtx->chan; + + /*** General setup ***/ + + pOp->minDurUsec = pBigCtx->syncDelayUsec; + pOp->maxDurUsec = pBigCtx->syncDelayUsec; + + /*** BIS setup ***/ + + pBis->execCback = lctrSlvBigBeginOp; + + switch (pBigCtx->packing) + { + case LL_PACKING_INTERLEAVED: + pBis->txDataCback = lctrSlvBisTxCompletionInterleaved; + break; + + case LL_PACKING_SEQUENTIAL: + default: + pBis->txDataCback = lctrSlvBisTxCompletionSequential; + break; + } + + /*** Commit operation ***/ + + if (!SchRmAdd(LCTR_BIG_TO_RM_HANDLE(pBigCtx), SCH_RM_PREF_PERFORMANCE, + pBigCtx->isoInterUsec, pBigCtx->isoInterUsec, pOp->minDurUsec, + NULL, lctrGetBigRefTime)) + { + LL_TRACE_WARN1("Could not schedule bigHandle=%u", pBigCtx->handle); + return LL_ERROR_CODE_CONN_REJ_LIMITED_RESOURCES; + } + + const uint32_t curTime = PalBbGetCurrentTime(); + uint32_t offsetUsec = SchRmGetOffsetUsec(pOp->minDurUsec, + LCTR_BIG_TO_RM_HANDLE(pBigCtx), curTime); + pOp->dueUsec = curTime + offsetUsec; + + while (TRUE) + { + lctrSelectBigChannels(pBigCtx); + + if (SchInsertAtDueTime(pOp, NULL)) + { + break; + } + + LL_TRACE_WARN1("!!! BIG schedule conflict handle=%u", pBigCtx->handle); + + /* Advance to next interval. */ + pBigCtx->eventCounter += 1; + pOp->dueUsec += pBigCtx->isoInterUsec; + } + + LL_TRACE_INFO2(" >>> BIG started, handle=%u, numBis=%u <<<", pBigCtx->handle, pBigCtx->numBis); + LL_TRACE_INFO3(" bn=%u, nse=%u, irc=%u", pBigCtx->bn, pBigCtx->nse, pBigCtx->irc); + LL_TRACE_INFO3(" pto=%u, framing=%u, packing=%u", pBigCtx->pto, pBigCtx->framing, pBigCtx->packing); + LL_TRACE_INFO1(" isoInterUsec=%u", pBigCtx->isoInterUsec); + LL_TRACE_INFO1(" bisSpaceUsec=%u", pBigCtx->bisSpaceUsec); + LL_TRACE_INFO1(" subInterUsec=%u", pBigCtx->subInterUsec); + LL_TRACE_INFO1(" seedAccAddr=0x%08x", pBigCtx->seedAccAddr); + LL_TRACE_INFO1(" pBod=0x%08x", pOp); + + return LL_SUCCESS; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis.c new file mode 100644 index 00000000000..7bba985c83d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis.c @@ -0,0 +1,1843 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connected isochronous stream main implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis.h" +#include "lctr_int_iso.h" +#include "lctr_int_conn.h" +#include "lctr_int.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "bb_api.h" +#include "pal_bb.h" +#include "pal_crypto.h" +#include "wsf_assert.h" +#include "wsf_buf.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief CIS context table. */ +lctrCisCtx_t *pLctrCisTbl; + +/*! \brief CIG context table. */ +lctrCigCtx_t *pLctrCigTbl; + +/*! \brief CIS message. */ +lctrCisMsg_t *pLctrCisMsg; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Update channel parameter. + * + * \param pCisCtx CIS context. + * \param chanMask Channel mask. + */ +/*************************************************************************************************/ +static void LctrCisUpdateChanParam(lctrCisCtx_t *pCisCtx, uint64_t chanMask) +{ + LL_TRACE_INFO1("LctrCisUpdateChanParam cisHandle=%u", pCisCtx->cisHandle); + LL_TRACE_INFO1("LctrCisUpdateChanParam, chanMask=%u", chanMask); + + pCisCtx->chanParam.chanMask = chanMask; + LmgrBuildRemapTable(&pCisCtx->chanParam); + pCisCtx->chIdx = LmgrSelectNextChannel(&pCisCtx->chanParam, pCisCtx->cisEvtCounter, 0, TRUE); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Allocate a CIS context. + * + * \param pCigCtx Pointer to the CIG context. + * + * \return CIS context or NULL if at capacity. + */ +/*************************************************************************************************/ +lctrCisCtx_t *lctrAllocCisCtx(lctrCigCtx_t *pCigCtx) +{ + for (uint16_t i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if (!pCisCtx->enabled) + { + memset(pCisCtx, 0, sizeof(lctrCisCtx_t)); + + pCisCtx->enabled = TRUE; + pCisCtx->cisHandle = LCTR_FIRST_CIS_HANDLE + i; + + /* Setup LLCP timer. */ + pCisCtx->tmrProcRsp.handlerId = lmgrPersistCb.handlerId; + lctrMsgHdr_t *pMsg = (lctrMsgHdr_t *)&pCisCtx->tmrProcRsp.msg; + pMsg->handle = pCisCtx->aclHandle; + pMsg->dispId = LCTR_DISP_CONN; + pMsg->event = LCTR_CONN_TMR_CIS_LLCP_RSP_EXP; + + /* Setup supervision timer. */ + pCisCtx->tmrSupTimeout.handlerId = lmgrPersistCb.handlerId; + pMsg = (lctrMsgHdr_t *)&pCisCtx->tmrSupTimeout.msg; + pMsg->handle = pCisCtx->cisHandle; + pMsg->dispId = LCTR_DISP_CIS; + pMsg->event = LCTR_CONN_TERM_SUP_TIMEOUT; + + /* Initialize data path info. */ + pCisCtx->dataPathInCtx.id = LL_ISO_DATA_PATH_DISABLED; + pCisCtx->dataPathOutCtx.id = LL_ISO_DATA_PATH_DISABLED; + + /* TODO: Update this value when needed. */ + pCisCtx->transLatUsec = LL_ISO_TRANSPORT_LAT_MIN; + + pCisCtx->cigId = pCigCtx->cigId; /* Save the CIG ID. */ + + return pCisCtx; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup context, clean CIG context if necessary for slave. + * + * \param pCisCtx CIS context to free. + */ +/*************************************************************************************************/ +void lctrCleanupCtx(lctrCisCtx_t *pCisCtx) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + WSF_ASSERT(pCigCtx); + + if (lctrCisIsHeadCis(&pCigCtx->list, pCisCtx) == TRUE) + { + pCigCtx->headCisRmved = TRUE; + pCigCtx->firstRxStartTsUsec = pCisCtx->data.slv.firstRxStartTsUsec; + + if (pCigCtx->packing == LL_PACKING_INTERLEAVED) + { + pCigCtx->offsetUsec = pCisCtx->delayUsec; + } + else + { + pCigCtx->offsetUsec = pCisCtx->subIntervUsec * pCisCtx->nse; + } + } + + if (pCisCtx->role == LL_ROLE_SLAVE) + { + lctrFreeCisCtx(pCisCtx); + + (void)lctrCisRemove(&pCigCtx->list, pCisCtx); /* Result could be FALSE since BOD might not be in list. */ + + if (lctrCisIsListEmpty(&pCigCtx->list)) + { + lctrFreeCigCtx(pCigCtx); + } + } + else + { + /* CIS context for master will not be freed until CIG is removed. */ + + (void)lctrCisRemove(&pCigCtx->list, pCisCtx); /* Result could be FALSE since BOD might not be in list. */ + + if (lctrCisIsListEmpty(&pCigCtx->list)) + { + if (pCigCtx->isRmAdded == TRUE) + { + SchRmRemove(LCTR_GET_CIG_RM_HANDLE(pCigCtx)); + pCigCtx->isRmAdded = FALSE; + } + } + + /* CIG is removed through host command, unless resetted. */ + + if ((lctrResetEnabled == TRUE)) + { + lctrFreeCisCtx(pCisCtx); + + if (lctrCisIsListEmpty(&pCigCtx->list)) + { + lctrFreeCigCtx(pCigCtx); + } + } + } + + /* Send CIS message to continue reset. This message will not be processed since the CIS context has been cleared. */ + if (lctrResetEnabled) + { + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_CLOSED); + } + + void *pIsoBuf; + uint8_t handlerId; + while ((pIsoBuf = WsfMsgDeq(&pCisCtx->isoalTxCtx.pendingSduQ, &handlerId)) != NULL) + { + WsfMsgFree(pIsoBuf); + } + + lctrIsoalRxDataPathClear(&pCisCtx->isoalRxCtx, pCisCtx->framing); +} + +/*************************************************************************************************/ +/*! + * \brief Free a CIS context. + * + * \param pCisCtx CIS context to free. + */ +/*************************************************************************************************/ +void lctrFreeCisCtx(lctrCisCtx_t *pCisCtx) +{ + uint8_t *pBuf; + uint8_t numTxBufs; + wsfHandlerId_t handlerId; + + WSF_ASSERT(pCisCtx->enabled); + pCisCtx->enabled = FALSE; + + /* Clean up receive context. */ + lctrIsoOutDataPathClear(&pCisCtx->dataPathOutCtx); + + /* Flush remaining transmit packets. */ + numTxBufs = lctrCisTxQueueClear(pCisCtx); + + /* Flush remaining transmit packets. */ + while ((pBuf = WsfMsgDeq(&pCisCtx->txIsoQ, &handlerId)) != NULL) + { + lctrDataTxIncAvailBuf(); + numTxBufs++; + + WsfMsgFree(pBuf); + } + + /* Flush remaining Tx/Rx flush timeout list. */ + lctrCisFtListClear(&pCisCtx->txFtParamList); + lctrCisFtListClear(&pCisCtx->rxFtParamList); + + /* Cleanup timers. */ + WsfTimerStop(&pCisCtx->tmrSupTimeout); + WsfTimerStop(&pCisCtx->tmrProcRsp); + +} + +/*************************************************************************************************/ +/*! + * \brief Find a CIS by handle. + * + * \param cisHandle CIS handle. + * + * \return CIS or NULL if not found. + */ +/*************************************************************************************************/ +lctrCisCtx_t *lctrFindCisByHandle(uint16_t cisHandle) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->cisHandle == cisHandle) && + (pCisCtx->enabled)) + { + return pCisCtx; + } + } + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Find a CIS by CIG ID and CIS ID. + * + * \param cigId CIG identifier. + * \param cisId CIS identifier. + * + * \return CIS or NULL if not found. + */ +/*************************************************************************************************/ +lctrCisCtx_t *lctrFindCisById(uint8_t cigId, uint8_t cisId) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled) && + (pCisCtx->cigId == cigId) && + (pCisCtx->cisId == cisId)) + { + return pCisCtx; + } + } + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a CIG context. + * + * \param cigId CIG ID. + * + * \return CIG context or NULL if at capacity. + */ +/*************************************************************************************************/ +lctrCigCtx_t *lctrAllocCigCtx(uint8_t cigId) +{ + for (uint16_t i = 0; i < pLctrRtCfg->maxCig; i++) + { + lctrCigCtx_t *pCigCtx = &pLctrCigTbl[i]; + + if (!pCigCtx->enabled) + { + memset(pCigCtx, 0, sizeof(lctrCigCtx_t)); + + /* pCigCtx->numCisEsted = 0; */ + pCigCtx->enabled = TRUE; + pCigCtx->cigId = cigId; + pCigCtx->cigHandle = i; + + /* Initialize the CIS list. */ + pCigCtx->list.numNodes = 0; + pCigCtx->list.pHead = NULL; + pCigCtx->list.pTail = NULL; + + LmgrIncResetRefCount(); + + /* Enable BB. */ + BbStart(BB_PROT_BLE); + + return pCigCtx; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Free a CIG context. + * + * \param pCigCtx CIG context to free. + */ +/*************************************************************************************************/ +void lctrFreeCigCtx(lctrCigCtx_t *pCigCtx) +{ + WSF_ASSERT(pCigCtx->enabled); + + pCigCtx->enabled = FALSE; + pCigCtx->roleData.slv.lastActiveEvent = 0; + pCigCtx->isBodBuilt = FALSE; + pCigCtx->isBodStarted = FALSE; + pCigCtx->numCisEsted = 0; + + LmgrDecResetRefCount(); + + /* Disable BB. */ + BbStop(BB_PROT_BLE); +} + +/*************************************************************************************************/ +/*! + * \brief Find a CIG by CIG ID. + * + * \param cigId CIG identifier. + * + * \return CIG or NULL if not found. + */ +/*************************************************************************************************/ +lctrCigCtx_t *lctrFindCigById(uint8_t cigId) +{ + for (unsigned int i = 0; i < pLctrRtCfg->maxCig; i++) + { + lctrCigCtx_t *pCigCtx = &pLctrCigTbl[i]; + + if ((pCigCtx->enabled) && + (pCigCtx->cigId == cigId)) + { + return pCigCtx; + } + } + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available CIG contexts. + * + * \return Number of available CIS contexts. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumAvailCigCtx() +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pLctrRtCfg->maxCig; i++) + { + lctrCigCtx_t *pCigCtx = &pLctrCigTbl[i]; + + if (pCigCtx->enabled == FALSE) + { + count++; + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize connected isochronous stream memory resources. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + */ +/*************************************************************************************************/ +uint16_t LctrInitCisMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + uint8_t *pAvailMem = pFreeMem; + + /*** Advertising Set Context ***/ + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + LL_TRACE_INFO2(" RAM: %u x %u bytes -- CIS context", pLctrRtCfg->maxCis, sizeof(lctrCisCtx_t)); + + /* Allocate CIS context memory. */ + pLctrCisTbl = (lctrCisCtx_t *)pAvailMem; + pAvailMem += sizeof(lctrCisCtx_t) * pLctrRtCfg->maxCis; + + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + LL_TRACE_INFO2(" RAM: %u x %u bytes -- CIG context", pLctrRtCfg->maxCig, sizeof(lctrCigCtx_t)); + + /* Allocate CIG context memory. */ + pLctrCigTbl = (lctrCigCtx_t *)pAvailMem; + pAvailMem += sizeof(lctrCigCtx_t) * pLctrRtCfg->maxCig; + + if (((uint32_t)(pAvailMem - pFreeMem)) > freeMemSize) + { + LL_TRACE_ERR2("LctrInitCisMem: failed to allocate CIS, need=%u available=%u", (pAvailMem - pFreeMem), freeMemSize); + WSF_ASSERT(FALSE); + return 0; + } + + lmgrPersistCb.cisCtxSize = sizeof(lctrCisCtx_t); + lmgrPersistCb.cigCtxSize = sizeof(lctrCigCtx_t); + + return (pAvailMem - pFreeMem); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize flush timeout parameters. + * + * \param pFtParam Pointer to the flush parameter. + * \param bn Burst number. + * \param ft Flush time. + * \param nse Number of subevent. + */ +/*************************************************************************************************/ +void lctrCisInitFtParam(lctrFtParam_t *pFtParam, uint8_t bn, uint8_t ft, uint8_t nse) +{ + pFtParam->pduRcved = FALSE; + pFtParam->pduAcked = FALSE; + pFtParam->pduCounter = 0; + pFtParam->subEvtCounter = 0; + pFtParam->bn = bn; + pFtParam->intervalTotal = ft; + pFtParam->intervalCounter = 0; + + if (bn == 1) + { + /* BN = 1, numSubEvtFt[0] = BN * NSE */ + pFtParam->lastSubEvtFt[0] = bn * nse; + pFtParam->isPduDone[0] = FALSE; + pFtParam->pduType[0] = LCTR_CIS_PDU_DEFAULT; + } + else + { + /* BN > 1, i = 0, numSubEvtFt[i] = FLOOR(NSE/BN) + MOD(NSE, BN) */ + uint8_t floor = nse / bn; + + pFtParam->lastSubEvtFt[0] = floor + (nse - (floor * bn)); + pFtParam->isPduDone[0] = FALSE; + + /* BN > 1, i > 0, numSubEvtFt[i] = floor */ + for (unsigned int i = 1; i < WSF_MIN(bn, LCTR_MAX_BN); i++) + { + pFtParam->lastSubEvtFt[i] = floor + pFtParam->lastSubEvtFt[i-1]; + pFtParam->isPduDone[i] = FALSE; + pFtParam->pduType[i] = LCTR_CIS_PDU_DEFAULT; + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if the CIS is established or not. + * + * \param pCisCtx CIS context. + * + * \return TRUE if CIS is established. + */ +/*************************************************************************************************/ +bool_t lctrIsCisEst(lctrCisCtx_t *pCisCtx) +{ + return (pCisCtx->state == LCTR_CIS_STATE_EST) ? TRUE : FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of available CIS contexts. + * + * \return Number of available CIS contexts. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumAvailCisCtx() +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if (pCisCtx->enabled == FALSE) + { + count++; + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS contexts that are already set up(enabled). + * + * \param pSetCigParam Set CIG parameters. + * + * \return Number of CIS contexts that are already set up(enabled). + */ +/*************************************************************************************************/ +uint8_t lctrGetNumEnabledCisCtx(LlCisCigParams_t *pSetCigParam) +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + if (lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId)) + { + count++; + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS contexts that are enabled(in use). + * + * \param pSetCigParam Set CIG parameters. + * + * \return Number of CIS contexts that are already set up(enabled). + */ +/*************************************************************************************************/ +uint8_t lctrGetNumEnabledCisCtxTest(LlCisCigParamsTest_t *pSetCigParam) +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + if (lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId)) + { + count++; + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS contexts that are already established. + * + * \param pSetCigParam Set CIG parameters. + * + * \return Number of CIS contexts that are established. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumEstCisCtx(LlCisCigParams_t *pSetCigParam) +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + lctrCisCtx_t *pCisCtx; + + if ((pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId))) + { + if (lctrIsCisEst(pCisCtx)) + { + count++; + } + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS contexts that are already established(enabled) for testing. + * + * \param pSetCigParam Set CIG parameters. + * + * \return Number of CIS contexts that are established. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumEstCisCtxTest(LlCisCigParamsTest_t *pSetCigParam) +{ + uint8_t count = 0; + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + lctrCisCtx_t *pCisCtx; + + if ((pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId))) + { + if (lctrIsCisEst(pCisCtx)) + { + count++; + } + } + } + + return count; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of CIS contexts that are already established(enabled) in a CIG. + * + * \param pCigCtx CIG context. + * + * \return Number of CIS contexts that are established. + */ +/*************************************************************************************************/ +uint8_t lctrGetNumEstCisCtxByCigCtx(lctrCigCtx_t *pCigCtx) +{ + WSF_ASSERT(pCigCtx); + + return pCigCtx->numCisEsted; +} + +/*************************************************************************************************/ +/*! + * \brief CIS message dispatcher. + * + * \param pMsg Pointer to message buffer. + */ +/*************************************************************************************************/ +void lctrCisDisp(lctrCisMsg_t *pMsg) +{ + lctrCisCtx_t *pCisCtx; + + if (pMsg->hdr.dispId != LCTR_DISP_BCST) + { + WSF_ASSERT(pMsg->hdr.handle < (LCTR_FIRST_BIS_HANDLE)); /* The beginning of BIS handles is the upper bound of CIS handles. */ + + if ((pCisCtx = lctrFindCisByHandle(pMsg->hdr.handle)) != NULL) + { + pLctrCisMsg = pMsg; + + lctrCisExecuteSm(pCisCtx, pMsg->hdr.event); + } + } + else + { + /* Clear CIG handles. */ + lctrCleanupCigCtx(); + } +} + +/*************************************************************************************************/ +/*! + * \brief CIS conflict resolution handler. + * + * \param pNewOp New BOD. + * \param pExistOp Existing BOD. + * + * \return Prioritized BOD. + * + * Prioritize BLE connection at most risk for termination. + */ +/*************************************************************************************************/ +BbOpDesc_t *lctrCisResolveConflict(BbOpDesc_t *pNewOp, BbOpDesc_t *pExistOp) +{ + /* TODO Add conflict resolution handler */ + + return pExistOp; +} + +/*************************************************************************************************/ +/*! + * \brief Set up the channel parameter. + * + * \param pCisCtx CIS context. + * \param chanMask Channel mask. + */ +/*************************************************************************************************/ +void lctrCisSetupChanParam(lctrCisCtx_t *pCisCtx, uint64_t chanMask) +{ + pCisCtx->chanParam.chanMask = chanMask; + LmgrBuildRemapTable(&pCisCtx->chanParam); + pCisCtx->chanParam.usedChSel = LL_CH_SEL_2; + pCisCtx->chanParam.chIdentifier = (pCisCtx->accessAddr >> 16) ^ + (pCisCtx->accessAddr >> 0); + pCisCtx->chIdx = LmgrSelectNextChannel(&pCisCtx->chanParam, pCisCtx->cisEvtCounter, 0, TRUE); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); + pCisCtx->subEvtCounter = 0; +} + +/*************************************************************************************************/ +/*! + * \brief Update channel map triggered by host or peer. + * + * \param aclHandle ACL handle. + */ +/*************************************************************************************************/ +void LctrCisUpdateChanMap(uint16_t aclHandle) +{ + LL_TRACE_INFO1("LctrCisUpdateChanMap aclHandle=%u", aclHandle); + + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->aclHandle == aclHandle) && + (pCisCtx->enabled)) + { + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + LctrCisUpdateChanParam(pCisCtx, pCtx->chanMask); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize cipher block for CIS. + * + * \param pCisCtx Connection context. + */ +/*************************************************************************************************/ +void lctrCisSetupEncrypt(lctrCisCtx_t *pCisCtx) +{ + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + WSF_ASSERT(pCtx); + + PalCryptoEnc_t * const pEnc = &pCisCtx->bleData.chan.enc; + + PalCryptoAesEcb(pCtx->ltk, pEnc->sk, pCtx->skd); + + WSF_ASSERT(lctrInitCipherBlkHdlr); + memcpy(pEnc->iv, pCtx->iv, sizeof(pEnc->iv)); + uint8_t *pTemp, accAddr[4]; + pTemp = accAddr; + UINT32_TO_BSTREAM(pTemp, pCisCtx->accessAddr) + pEnc->iv[0] ^= accAddr[0]; + pEnc->iv[1] ^= accAddr[1]; + pEnc->iv[2] ^= accAddr[2]; + pEnc->iv[3] ^= accAddr[3]; + pEnc->dir = (pCisCtx->role == LL_ROLE_MASTER) ? 1 : 0; /* master = 1; slave = 0 */ + pEnc->type = PAL_BB_TYPE_CIS; + + lctrInitCipherBlkHdlr(pEnc, pCisCtx->cisHandle, pEnc->dir); + + pEnc->enaEncrypt = pCtx->bleData.chan.enc.enaEncrypt; + pEnc->enaDecrypt = pCtx->bleData.chan.enc.enaDecrypt; +} + +/************************************************************************************************** + Utility functions to manipulate the CIS linked list. +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Create a node. + * + * \param pCisCtx CIS context. + * + * \return Pointer to the node or NULL if creation fails. + */ +/*************************************************************************************************/ +static lctrCisNode_t * lctrCisCreateNode(lctrCisCtx_t *pCisCtx) +{ + lctrCisNode_t *pNew = NULL; + + if ((pNew = (lctrCisNode_t *)WsfBufAlloc(sizeof(lctrCisNode_t))) != NULL) + { + pNew->pNext = NULL; + pNew->pCisCtx = pCisCtx; + } + + return pNew; +} + +/*************************************************************************************************/ +/*! + * \brief Insert at the head of the list. + * + * \param pList Pointer to the list. + * \param pCisCtx CIS context. + * + * \return True if successfully insert at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisInsertHead(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx) +{ + lctrCisNode_t *pTemp = NULL; + + if ((pTemp = lctrCisCreateNode(pCisCtx)) == NULL) + { + return FALSE; + } + + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + pList->pHead = pList->pTail = pTemp; + } + else + { + /* List is not empty. */ + pTemp->pNext = pList->pHead; + pList->pHead = pTemp; + } + pList->numNodes++; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Insert at the tail of the list. + * + * \param pList Pointer to the list. + * \param pCisCtx CIS context. + * + * \return True if successfully insert at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisInsertTail(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx) +{ + lctrCisNode_t *pTemp = NULL; + + if ((pTemp = lctrCisCreateNode(pCisCtx)) == NULL) + { + return FALSE; + } + + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + pList->pHead = pList->pTail = pTemp; + } + else + { + /* List is not empty. */ + pList->pTail->pNext = pTemp; + pList->pTail = pTemp; + } + pList->numNodes++; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove at the head of the list. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisRemoveHead(lctrCisList_t *pList) +{ + lctrCisNode_t *pTemp = NULL; + + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + else + { + /* List is not empty. */ + pTemp = pList->pHead; + pList->pHead = pTemp->pNext; + WsfBufFree(pTemp); + } + pList->numNodes--; + + if (lctrCisIsListEmpty(pList)) + { + pList->pTail = NULL; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove at the tail of the list. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the tail, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisRemoveTail(lctrCisList_t *pList) +{ + lctrCisNode_t *pTemp = NULL; + + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + else if (pList->numNodes == 1) + { + /* List has only one node. */ + pTemp = pList->pTail; + WsfBufFree(pTemp); + pList->pHead = pList->pTail = NULL; + } + else + { + /* List has more than one node. */ + pTemp = pList->pHead; + + /* Traverse to the second last. */ + while (pTemp->pNext->pNext != NULL) + { + pTemp = pTemp->pNext; + } + + WsfBufFree(pTemp->pNext); /* Free the tail. */ + pTemp->pNext = NULL; + pList->pTail = pTemp; + } + pList->numNodes--; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove at the middle of the list. + * + * \param pList Pointer to the list. + * \param pCisCtx Pointer to the CIS context to remove + * + * \return True if successfully remove at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisRemoveMiddle(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx) +{ + lctrCisNode_t *pTemp = NULL; + lctrCisNode_t *pRemove = NULL; + + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + else + { + /* List is not empty. */ + pTemp = pList->pHead; + + while (pTemp->pNext != pList->pTail) + { + if (pTemp->pNext->pCisCtx == pCisCtx) + { + pRemove = pTemp->pNext; + pTemp->pNext = pTemp->pNext->pNext; + WsfBufFree(pRemove); + pList->numNodes--; + return TRUE; + } + pTemp = pTemp->pNext; + } + } + + /* Cannot fine the CIS context in the linked list. */ + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove a CIS context from the list. + * + * \param pList Pointer to the list. + * \param pCisCtx Pointer to the CIS context to remove + * + * \return True if successfully remove at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisRemove(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx) +{ + if (lctrCisIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + + if (pList->pHead->pCisCtx == pCisCtx) + { + return lctrCisRemoveHead(pList); + } + else if (pList->pTail->pCisCtx == pCisCtx) + { + return lctrCisRemoveTail(pList); + } + else + { + return lctrCisRemoveMiddle(pList, pCisCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if the list is empty or not. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the tail, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisIsListEmpty(lctrCisList_t *pList) +{ + return (pList->numNodes == 0) ? TRUE : FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Return the number of elements in the list. + * + * \param pList Pointer to the list. + * + * \return Number of elements in the list. + */ +/*************************************************************************************************/ +uint8_t lctrCisGetListCount(lctrCisList_t *pList) +{ + return pList->numNodes; +} + +/*************************************************************************************************/ +/*! + * \brief Return the CIS context at the head of the linked list. + * + * \param pList Pointer to the list. + * + * \return NULL or pointer to the CIS context at the head of the linked list. + */ +/*************************************************************************************************/ +lctrCisCtx_t * lctrCisGetHeadCis(lctrCisList_t *pList) +{ + if (lctrCisIsListEmpty(pList)) + { + return NULL; + } + + return pList->pHead->pCisCtx; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the input context is the head in the linked list. + * + * \param pList Pointer to the list. + * \param pCisCtx Pointer to the CIS context. + * + * \return TRUE if the input context is the head in the linked list, FALSE otherwise + */ +/*************************************************************************************************/ +bool_t lctrCisIsHeadCis(lctrCisList_t *pList, lctrCisCtx_t *pCisCtx) +{ + if (lctrCisIsListEmpty(pList)) + { + return FALSE; + } + + return (pList->pHead->pCisCtx == pCisCtx ? TRUE : FALSE); +} + +/*************************************************************************************************/ +/*! + * \brief Return the next CIS context after the current CIS context in the linked list. + * + * \param pList Pointer to the list. + * \param pCurCisCtx Current CIS. + * + * \return NULL or pointer to the next CIS context after the current CIS context in the linked list. + */ +/*************************************************************************************************/ +lctrCisCtx_t * lctrCisGetNextCis(lctrCisList_t *pList, lctrCisCtx_t *pCurCisCtx) +{ + if (lctrCisIsListEmpty(pList)) + { + return NULL; + } + + lctrCisNode_t *pTempNode = pList->pHead; + + while (pTempNode) + { + if (pTempNode->pCisCtx == pCurCisCtx) + { + if (pTempNode->pNext) + { + return pTempNode->pNext->pCisCtx; + } + else + { + return NULL; + } + } + + pTempNode = pTempNode->pNext; + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Return the next CIS context after the current CIS context in the linked list. + * + * \param pList Pointer to the list. + * \param pCurCisCtx Current CIS. + * + * \return NULL or pointer to the next CIS context after the current CIS context in the linked list. + */ +/*************************************************************************************************/ +lctrCisCtx_t * lctrCisGetPreCis(lctrCisList_t *pList, lctrCisCtx_t *pCurCisCtx) +{ + if (lctrCisIsListEmpty(pList)) + { + return NULL; + } + + lctrCisNode_t *pTempNode = pList->pHead; + + while (pTempNode->pNext) + { + if (pTempNode->pNext->pCisCtx == pCurCisCtx) + { + return pTempNode->pCisCtx; + } + pTempNode = pTempNode->pNext; + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Check whether all the interleaved CISs in the CIG are done or not. + * + * \param pList Pointer to the CIS list in the CIG. + * + * \return TRUE if all the CISs in the CIG are done, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisAreCisCtxDone(lctrCisList_t *pList) +{ + lctrCisNode_t *pTempNode = pList->pHead; + + while (pTempNode) + { + if (pTempNode->pCisCtx->cisDone == FALSE) + { + return FALSE; + } + + pTempNode = pTempNode->pNext; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Clear the cisDone flag for all the CISs in the CIG. + * + * \param pList Pointer to the CIS list in the CIG. + */ +/*************************************************************************************************/ +void lctrCisClearCisDone(lctrCisList_t *pList) +{ + lctrCisNode_t *pTempNode = pList->pHead; + + while (pTempNode) + { + pTempNode->pCisCtx->cisDone = FALSE; + pTempNode = pTempNode->pNext; + } +} + +/*************************************************************************************************/ +/*! + * \brief Set the cisDone flag for all the CISs after the CIS, including the current one. + * + * \param pList Pointer to the CIS list in the CIG. + * \param pCurCisCtx Current CIS. + */ +/*************************************************************************************************/ +void lctrCisSetCisDone(lctrCisList_t *pList, lctrCisCtx_t *pCurCisCtx) +{ + lctrCisNode_t *pTgtNode = NULL, *pTempNode = pList->pHead; + + while (pTempNode) + { + if (pTempNode->pCisCtx == pCurCisCtx) + { + pTgtNode = pTempNode; + break; + } + pTempNode = pTempNode->pNext; + } + + if (pTgtNode == NULL) + { + return; + } + else + { + pTempNode = pTgtNode; + + while (pTempNode) + { + pTempNode->pCisCtx->cisDone = TRUE; + pTempNode = pTempNode->pNext; + } + } +} + +/************************************************************************************************** + Utility functions to manipulate the CIS Tx/Rx Ft list. +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Create a flush timeout node. + * + * \param pFtParam Flush timeout parameters. + * + * \return Pointer to the node or NULL if creation fails. + */ +/*************************************************************************************************/ +lctrFtParamNode_t * lctrCisFtCreateFtParamNode(lctrFtParam_t *pFtParam) +{ + lctrFtParamNode_t *pNew = NULL; + + if ((pNew = (lctrFtParamNode_t *)WsfBufAlloc(sizeof(lctrFtParamNode_t))) != NULL) + { + pNew->pNext = NULL; + memcpy(&pNew->ftParam, pFtParam, sizeof(lctrFtParam_t)); + } + + return pNew; +} + +/*************************************************************************************************/ +/*! + * \brief Insert at the head of the list. + * + * \param pList Pointer to the list. + * \param pFtParam Flush timeout parameters. + * + * \return True if successfully insert at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisFtInsertHead(lctrFtParamList_t *pList, lctrFtParam_t *pFtParam) +{ + lctrFtParamNode_t *pTemp = NULL; + + if ((pTemp = lctrCisFtCreateFtParamNode(pFtParam)) == NULL) + { + return FALSE; + } + + if (lctrCisFtIsListEmpty(pList)) + { + /* List is empty. */ + pList->pHead = pList->pTail = pTemp; + } + else + { + /* List is not empty. */ + pTemp->pNext = pList->pHead; + pList->pHead = pTemp; + } + pList->numNodes++; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Insert at the tail of the list. + * + * \param pList Pointer to the list. + * \param pFtParam Flush timeout parameters. + * + * \return True if successfully insert at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisFtInsertTail(lctrFtParamList_t *pList, lctrFtParam_t *pFtParam) +{ + lctrFtParamNode_t *pTemp = NULL; + + if ((pTemp = lctrCisFtCreateFtParamNode(pFtParam)) == NULL) + { + return FALSE; + } + + if (lctrCisFtIsListEmpty(pList)) + { + /* List is empty. */ + pList->pHead = pList->pTail = pTemp; + } + else + { + /* List is not empty. */ + pList->pTail->pNext = pTemp; + pList->pTail = pTemp; + } + pList->numNodes++; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove at the head of the list. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the head, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisFtRemoveHead(lctrFtParamList_t *pList) +{ + lctrFtParamNode_t *pTemp = NULL; + + if (lctrCisFtIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + else + { + /* List is not empty. */ + pTemp = pList->pHead; + pList->pHead = pTemp->pNext; + WsfBufFree(pTemp); + } + pList->numNodes--; + + if (lctrCisFtIsListEmpty(pList)) + { + pList->pTail = NULL; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Remove at the tail of the list. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the tail, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisFtRemoveTail(lctrFtParamList_t *pList) +{ + lctrFtParamNode_t *pTemp = NULL; + + if (lctrCisFtIsListEmpty(pList)) + { + /* List is empty. */ + return FALSE; + } + else if (pList->numNodes == 1) + { + /* List has only one node. */ + pTemp = pList->pTail; + WsfBufFree(pTemp); + pList->pHead = pList->pTail = NULL; + } + else + { + /* List has more than one node. */ + pTemp = pList->pHead; + + /* Traverse to the second last. */ + while (pTemp->pNext->pNext != NULL) + { + pTemp = pTemp->pNext; + } + + WsfBufFree(pTemp->pNext); /* Free the tail. */ + pTemp->pNext = NULL; + pList->pTail = pTemp; + } + pList->numNodes--; + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Clear the flush timeout list. + * + * \param pList Pointer to the list. + */ +/*************************************************************************************************/ +void lctrCisFtListClear(lctrFtParamList_t *pList) +{ + if (lctrCisFtIsListEmpty(pList)) + { + /* List is empty. */ + return; + } + + lctrFtParamNode_t *pTemp = pList->pHead; + + while (pTemp) + { + lctrCisFtRemoveHead(pList); + pTemp = pTemp->pNext; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if the list is empty or not. + * + * \param pList Pointer to the list. + * + * \return True if successfully remove at the tail, False otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCisFtIsListEmpty(lctrFtParamList_t *pList) +{ + return pList->numNodes == 0 ? TRUE : FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Set flags for CIS link termination. + * + * \param aclHandle ACL connection handle. + * + * \return TRUE if CIS is terminated, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCheckForCisLinkTerm(uint16_t aclHandle) +{ + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(aclHandle); + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(pCtx->llcpCisHandle); + + if (pCisCtx == NULL) + { + return FALSE; + } + + if (pCisCtx->termState == LCTR_CIS_TERM_STATE_TERMINATING) + { + /* Peer device is LL_TERMINATE_IND initiator. */ + if (pCtx->termAckReqd) /* Tx Ack required after Rx of LL_TERMINATE_IND */ + { + pCtx->termAckReqd = FALSE; + + if (pCtx->ackAfterCtrlPdu) /* guarantee Ack Tx'ed */ + { + lctrSendCisLlcpMsg(pCisCtx, LCTR_CIS_TERM_EVENT_CIS_TERM); + return TRUE; + } + } + /* Local device is LL_CIS_TERMINATE_IND initiator. */ + else if ((pCtx->llcpState == LCTR_LLCP_STATE_IDLE) || /* LL_TERMINATE_IND not pending */ + (pCtx->txArqQ.pHead == NULL)) /* guarantee LL_TERMINATE_IND is Ack'ed */ + /* i.e. "WsfQueueEmpty(&pCtx->txArqQ)" (optimized for ISR) */ + { + lctrSendCisLlcpMsg(pCisCtx, LCTR_CIS_TERM_EVENT_CIS_TERM); + return TRUE; + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Check if there is a CIS established for the ACL indicated by the aclHandle. + * + * \param aclHandle ACL connection handle. + * + * \return TRUE if there is a CIS established, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCheckIsCisEstAcl(uint16_t aclHandle) +{ + for (uint16_t i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled == TRUE) && + (pCisCtx->aclHandle == aclHandle) && + lctrIsCisEst(pCisCtx)) + + { + return TRUE; + } + } + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Check if CIS is established indicated by the cisHandle. + * + * \param cisHandle CIS connection handle. + * + * \return TRUE if CIS is established, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrCheckIsCisEstCis(uint16_t cisHandle) +{ + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(cisHandle); + + if ((pCisCtx->enabled == TRUE) && + lctrIsCisEst(pCisCtx)) + { + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Start LLCP timer. + * + * \param pCtx ACL Connection context. + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +void lctrCisStartLlcpTimer(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + if (lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_ENA_LLCP_TIMER)) + { + WsfTimerStartSec(&pCisCtx->tmrProcRsp, LL_T_PRT_SEC); + } +} + +/*************************************************************************************************/ +/*! + * \brief Stop LLCP timer. + * + * \param pCtx ACL Connection context. + * \param pCisCtx CIS Context. + */ +/*************************************************************************************************/ +void lctrCisStopLlcpTimer(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + if (lctrGetConnOpFlag(pCtx, LL_OP_MODE_FLAG_ENA_LLCP_TIMER)) + { + WsfTimerStop(&pCisCtx->tmrProcRsp); + } +} + +/*************************************************************************************************/ +/*! + * \brief Compute the duration in microseconds of an subevent for sequential packing. + * + * \param phyMToS PHY master to slave. + * \param phySToM PHY slave to master. + * \param plMToS Payload master to slave. + * \param plSToM Payload master to slave. + * + * \return Time in microseconds for the packet to be transferred on the medium. + */ +/*************************************************************************************************/ +uint32_t lctrCisCalcSubEvtDurationUsecSeq(uint8_t phyMToS, uint8_t phySToM, uint8_t plMToS, uint8_t plSToM) +{ + uint32_t duration = 0; + + /* MIC is always included since the scheduling is done when a CIS in the CIG is enabled for the first time + * and the encryption mode of other CISs in the CIG are unknown. */ + switch (phyMToS) + { + case BB_PHY_BLE_1M: + duration += LL_DATA_LEN_TO_TIME_1M(plMToS, TRUE); + break; + case BB_PHY_BLE_2M: + duration += LL_DATA_LEN_TO_TIME_2M(plMToS, TRUE); + break; + case BB_PHY_BLE_CODED: + duration += LL_DATA_LEN_TO_TIME_CODED_S8(plMToS, TRUE); + break; + } + + duration += LL_BLE_TIFS_US; + + /* MIC is always included since the scheduling is done when a CIS in the CIG is enabled for the first time + * and the encryption mode of other CISs in the CIG are unknown. */ + switch (phySToM) + { + case BB_PHY_BLE_1M: + duration += LL_DATA_LEN_TO_TIME_1M(plSToM, TRUE); + break; + case BB_PHY_BLE_2M: + duration += LL_DATA_LEN_TO_TIME_2M(plSToM, TRUE); + break; + case BB_PHY_BLE_CODED: + duration += LL_DATA_LEN_TO_TIME_CODED_S8(plSToM, TRUE); + break; + } + + duration += LL_BLE_TMSS_US; + + duration += pLctrRtCfg->cisSubEvtSpaceDelay; /* Add runtime config delay. */ + + return duration; +} + +/*************************************************************************************************/ +/*! + * \brief Compute the duration in microseconds of an sub event for interleaved packing. + * + * \param pSetCigParam CIG parameters. + * + * \return Time in microseconds for the packet to be transferred on the medium. + * + * \note This value includes preamble, access address, CRC and T_IFS. + */ +/*************************************************************************************************/ +uint32_t lctrCisCalcSubEvtDurationUsecInter(LlCisCigParams_t *pSetCigParam) +{ + uint32_t duration = 0; + + lctrCisCtx_t *pCisCtx; + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId); + + duration += lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + } + return duration; +} + +/*************************************************************************************************/ +/*! + * \brief Set default values for CIS. + */ +/*************************************************************************************************/ +void lctrCisDefaults(void) +{ + memset(pLctrCisTbl, 0, sizeof(lctrCisCtx_t) * pLctrRtCfg->maxCis); + memset(pLctrCigTbl, 0, sizeof(lctrCigCtx_t) * pLctrRtCfg->maxCig); +} + +/*************************************************************************************************/ +/*! + * \brief Generate and send a test payload. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrCisTxTestPayloadHandler(lctrCisCtx_t * pCisCtx) +{ + uint16_t maxSdu = (pCisCtx->role == LL_ROLE_MASTER) ? pCisCtx->sduSizeMToS : pCisCtx->sduSizeSToM; + uint8_t * pIsoBuf; + uint32_t pktCtr; + if ((pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) && (pCisCtx->testTxPktCtr == 0)) + { + pCisCtx->testTxPktCtr = pCisCtx->txPktCounter; + } + + pktCtr = pCisCtx->testTxPktCtr++; + pIsoBuf = lctrGenerateIsoTestData(pCisCtx->cisHandle, pCisCtx->testPldType, maxSdu, pktCtr); + + if (lmgrIsoCb.availTxBuf == 0) + { + LL_TRACE_WARN0("!!! ISO flow control detected; dropping Tx data PDU"); + + /* Drop packet due to out of Tx buffers condition. */ + WsfMsgFree(pIsoBuf); + pIsoBuf = NULL; /* Returned below. */ + } + + if (pIsoBuf == NULL) + { + /* Restore last payload counter since packet could not be generated. */ + pCisCtx->testTxPktCtr--; + return; + } + + LctrTxIso(pIsoBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Action function for cis power monitoring. + * + * \param rssi CIS RX RSSI. + * \param status rx status. + * \param phy phy. + * \param pConnCtx Connection context. +*************************************************************************************************/ +void lctrCisPowerMonitorCheckRssi(int8_t rssi, uint8_t status, uint8_t phy, lctrConnCtx_t *pConnCtx) +{ + if (!(pConnCtx->usedFeatSet & LL_FEAT_POWER_CONTROL_REQUEST)) + { + pConnCtx->monitoringState = LCTR_PC_MONITOR_DISABLED; + return; + } + + if (lmgrCb.opModeFlags & LL_OP_MODE_DISABLE_POWER_MONITOR) + { + return; + } + + int8_t sendReqDelta = 0; + + if ((rssi < pConnCtx->pclMonitorParam.autoMonitor.lowThreshold) || + (status != BB_STATUS_SUCCESS)) + { + pConnCtx->cisRssiExtremeTimeSpent++; + + if (pConnCtx->cisRssiExtremeTimeSpent >= pConnCtx->pclMonitorParam.autoMonitor.minTimeSpent) + { + if (!(pConnCtx->peerPwrLimits & LL_PWR_CONTROL_LIMIT_MAX_BIT)) + { + LL_TRACE_INFO1("RSSI too low, requesting increase in power. phy=%u", phy); + sendReqDelta = pConnCtx->pclMonitorParam.autoMonitor.requestVal; + } + pConnCtx->cisRssiExtremeTimeSpent = 0; + } + } + else if (rssi > pConnCtx->pclMonitorParam.autoMonitor.highThreshold) + { + pConnCtx->cisRssiExtremeTimeSpent++; + + if (pConnCtx->cisRssiExtremeTimeSpent >= pConnCtx->pclMonitorParam.autoMonitor.minTimeSpent) + { + if (!(pConnCtx->peerPwrLimits & LL_PWR_CONTROL_LIMIT_MIN_BIT)) + { + LL_TRACE_INFO1("RSSI too high, requesting decrease in power. phy=%u", phy); + sendReqDelta = -(pConnCtx->pclMonitorParam.autoMonitor.requestVal); + } + pConnCtx->cisRssiExtremeTimeSpent = 0; + } + } + else + { + pConnCtx->cisRssiExtremeTimeSpent = 0; + } + + if (sendReqDelta != 0) + { + lctrMsgPwrCtrlReq_t *pMsg; + if ((pMsg = (lctrMsgPwrCtrlReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = LCTR_GET_CONN_HANDLE(pConnCtx); + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_PWR_CTRL_REQ; + pMsg->delta = sendReqDelta; + pMsg->phy = phy; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Cleanup CIG contexts. + */ +/*************************************************************************************************/ +void lctrCleanupCigCtx() +{ + lctrCigCtx_t *pCigCtx; + for (uint8_t i = 0; i < pLctrRtCfg->maxCig; i++) + { + pCigCtx = &pLctrCigTbl[i]; + if (pCigCtx->enabled) + { + if (pCigCtx->numCisEsted == 0) + { + lctrFreeCigCtx(pCigCtx); + } + else + { + SchRemove(&pCigCtx->cigBod); + } + } + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_master.c new file mode 100644 index 00000000000..da28cbc1c4e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_master.c @@ -0,0 +1,1127 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connected isochronous stream master operation builder implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis.h" +#include "lctr_int_iso.h" +#include "lctr_int_cis_master.h" +#include "lctr_int_cis_slave.h" +#include "lctr_int_conn_master.h" +#include "lctr_int.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "bb_api.h" +#include "pal_bb.h" +#include "wsf_assert.h" +#include "wsf_buf.h" +#include "wsf_cs.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/*! \brief Create CIS pending parameters. */ +lctrCreateCisPend_t lctrMstCreateCisPend; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +extern uint8_t lctrChoosePreferredPhy(uint8_t val); + +/************************************************************************************************** + Internal functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief CIS master reset handler. + */ +/*************************************************************************************************/ +static void lctrCisMstResetHandler(void) +{ + BbBleCisSlaveInit(); + BbBleCisMasterInit(); + lctrCisDefaults(); + LmgrMstCisInit(); +} + +/*************************************************************************************************/ +/*! + * \brief Master Tx data pending task event handler. + */ +/*************************************************************************************************/ +static void lctrIsoTxPendingHandler(void) +{ + unsigned int i; + + for (i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled) && + !WsfQueueEmpty(&pCisCtx->txArqQ)) + { + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + SchReload(&pCigCtx->cigBod); + } + } +} + +/*************************************************************************************************/ +/*! + * \brief Host channel class update handler for CIS master. + * + * \param chanMap Updated channel map. + * + * \return Status code. + */ +/*************************************************************************************************/ +static uint8_t lctrMstCisChClassUpdate(uint64_t chanMap) +{ + uint16_t handle; + + /* Update for connections */ + for (handle = 0; handle < pLctrRtCfg->maxConn; handle++) + { + if ((LctrIsConnHandleEnabled(handle)) && + (LctrGetRole(handle) == LL_ROLE_MASTER)) + { + /* Update the channel map for CIS master as well. */ + LctrCisUpdateChanMap(handle); + } + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Check whether the parameters for the CIG can be scheduled or not. + * + * \param pCigCtx CIG context. + * + * \return TRUE if schedule is successful, otherwise FALSE. + */ +/*************************************************************************************************/ +static bool_t lctrCisMstCheckCigParams(lctrCigCtx_t *pCigCtx) +{ + /* Check whether the CIG could be scheduled within the interval. */ + if (pCigCtx->cigSyncDelayUsec >= (uint32_t)(LCTR_ISO_INT_TO_US(pCigCtx->isoInterval) - LL_BLE_TMSS_US)) + { + return FALSE; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Compute the duration in microseconds of an sub event for interleaved packing for + * testing purpose. + * + * \param pSetCigParamTest CIG parameter for test. + * + * \return Time in microseconds for the packet to be transferred on the medium. + * + * \note This value includes preamble, access address, CRC and T_IFS. + */ +/*************************************************************************************************/ +static uint32_t lctrCalcSubEvtDurationUsecInterTest(LlCisCigParamsTest_t *pSetCigParamTest) +{ + uint32_t duration = 0; + + lctrCisCtx_t *pCisCtx; + + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[i].cisId); + + duration += lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + } + return duration; +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new CIS or update an existing CIS. + * + * \param pCisCtx CIS context. + * \param pSetCigParam CIG parameters. + * \param pCisParam CIS parameters. + */ +/*************************************************************************************************/ +static void lctrSetCis(lctrCisCtx_t *pCisCtx, LlCisCigParams_t *pSetCigParam, LlCisCisParams_t *pCisParam) +{ + pCisCtx->cisId = pCisParam->cisId; + pCisCtx->sca = pSetCigParam->sca; + pCisCtx->packing = pSetCigParam->packing; + pCisCtx->framing = pSetCigParam->framing; + pCisCtx->accessAddr = lctrComputeAccessAddr(); + + if (pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + if (pSetCigParam->sduIntervalMToS <= 1250) + { + pSetCigParam->sduIntervalMToS = 1250; + } + if (pSetCigParam->sduIntervalSToM <= 1250) + { + pSetCigParam->sduIntervalSToM = 1250; + } + + pCisCtx->isoInterval = LL_MATH_DIV_1250(pSetCigParam->sduIntervalMToS); /* Make sure PDU interval the same as the SDU interval. Assume sduIntervalMToS equals sduIntervalSToM */ + pCisCtx->sduIntervalMToS = pSetCigParam->sduIntervalMToS; + pCisCtx->sduIntervalSToM = pSetCigParam->sduIntervalSToM; + pCisCtx->localDataPdu.maxTxLen = WSF_MIN(pCisParam->sduSizeMToS, pLctrRtCfg->maxIsoPduLen); + pCisCtx->localDataPdu.maxRxLen = WSF_MIN(pCisParam->sduSizeSToM, pLctrRtCfg->maxIsoPduLen); + pCisCtx->sduSizeMToS = pCisParam->sduSizeMToS; + pCisCtx->sduSizeSToM = pCisParam->sduSizeSToM; + pCisCtx->phyMToS = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCisParam->phyMToS)); + pCisCtx->phySToM = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCisParam->phySToM)); + pCisCtx->ftMToS = LlMathDivideUint32(pSetCigParam->transLatMToS * 1000, LCTR_ISO_INT_TO_US(pCisCtx->isoInterval)); + pCisCtx->ftSToM = LlMathDivideUint32(pSetCigParam->transLatSToM * 1000, LCTR_ISO_INT_TO_US(pCisCtx->isoInterval)); + + if (pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen * pCisCtx->localDataPdu.maxTxLen < pCisCtx->sduSizeMToS) + { + pCisCtx->bnMToS = pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen + 1; + } + else + { + pCisCtx->bnMToS = pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen; + } + + if (pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen * pCisCtx->localDataPdu.maxRxLen < pCisCtx->sduSizeSToM) + { + pCisCtx->bnSToM = pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen + 1; + } + else + { + pCisCtx->bnSToM = pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen; + } + + pCisCtx->nse = WSF_MAX(pCisCtx->bnSToM, pCisCtx->bnMToS) + WSF_MAX(pCisParam->rteMToS, pCisParam->rteSToM); + + LL_TRACE_INFO1("lctrSetCis, maxTxLen=%d", pCisCtx->localDataPdu.maxTxLen); + LL_TRACE_INFO1("lctrSetCis, sduMToS=%d", pCisCtx->sduSizeMToS); + LL_TRACE_INFO1("lctrSetCis, bnMToS=%d", pCisCtx->bnMToS); + + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + if (pSetCigParam->sduIntervalMToS <= 1250) + { + pSetCigParam->sduIntervalMToS = 1250; + } + if (pSetCigParam->sduIntervalSToM <= 1250) + { + pSetCigParam->sduIntervalSToM = 1250; + } + + pCisCtx->isoInterval = LL_MATH_DIV_1250(pSetCigParam->sduIntervalMToS); /* Make sure PDU interval the same as the SDU interval. Assume sduIntervalMToS equals sduIntervalSToM */ + pCisCtx->sduIntervalMToS = pSetCigParam->sduIntervalMToS; + pCisCtx->sduIntervalSToM = pSetCigParam->sduIntervalSToM; + pCisCtx->localDataPdu.maxTxLen = WSF_MIN(pCisParam->sduSizeMToS, pLctrRtCfg->maxIsoPduLen); + pCisCtx->localDataPdu.maxRxLen = WSF_MIN(pCisParam->sduSizeSToM, pLctrRtCfg->maxIsoPduLen); + pCisCtx->sduSizeMToS = pCisParam->sduSizeMToS; + pCisCtx->sduSizeSToM = pCisParam->sduSizeSToM; + pCisCtx->phyMToS = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCisParam->phyMToS)); + pCisCtx->phySToM = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCisParam->phySToM)); + pCisCtx->ftMToS = LlMathDivideUint32(pSetCigParam->transLatMToS * 1000, LCTR_ISO_INT_TO_US(pCisCtx->isoInterval)); + pCisCtx->ftSToM = LlMathDivideUint32(pSetCigParam->transLatSToM * 1000, LCTR_ISO_INT_TO_US(pCisCtx->isoInterval)); + + if (pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen * pCisCtx->localDataPdu.maxTxLen < pCisCtx->sduSizeMToS) + { + pCisCtx->bnMToS = pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen + 1; + } + else + { + pCisCtx->bnMToS = pCisCtx->sduSizeMToS / pCisCtx->localDataPdu.maxTxLen; + } + + if (pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen * pCisCtx->localDataPdu.maxRxLen < pCisCtx->sduSizeSToM) + { + pCisCtx->bnSToM = pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen + 1; + } + else + { + pCisCtx->bnSToM = pCisCtx->sduSizeSToM / pCisCtx->localDataPdu.maxRxLen; + } + + pCisCtx->nse = WSF_MAX(pCisCtx->bnSToM, pCisCtx->bnMToS) + WSF_MAX(pCisParam->rteMToS, pCisParam->rteSToM); + + LL_TRACE_INFO1("lctrSetCis, maxTxLen=%d", pCisCtx->localDataPdu.maxTxLen); + LL_TRACE_INFO1("lctrSetCis, sduMToS=%d", pCisCtx->sduSizeMToS); + LL_TRACE_INFO1("lctrSetCis, bnMToS=%d", pCisCtx->bnMToS); + } +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new CIG. + * + * \param pCigCtx CIG context. + * \param pSetCigParam CIG parameters. + */ +/*************************************************************************************************/ +static void lctrSetCig(lctrCigCtx_t *pCigCtx, LlCisCigParams_t *pSetCigParam) +{ + lctrCisCtx_t *pCisCtx, *pCisCtxTemp, *pCisCtxFirst; + + /* Calculate subevent interval and offset for each CIS. */ + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + if (pSetCigParam->packing == LL_PACKING_INTERLEAVED) + { + pCisCtx->subIntervUsec = lctrCisCalcSubEvtDurationUsecInter(pSetCigParam); + pCisCtx->delayUsec = lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + } + else + { + /* LL_PACKING_SEQUENTIAL */ + pCisCtx->subIntervUsec = lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + pCisCtx->delayUsec = pCisCtx->subIntervUsec; + } + + /* The formula is (2 * CIS_interval * (master_sca + slave_sca) / 1000000) */ + WSF_ASSERT((uint64_t)pCisCtx->subIntervUsec > WSF_MIN(LL_BLE_TMSS_US, LL_MATH_DIV_10E6(2 * LCTR_ISO_INT_TO_US(pCisCtx->isoInterval) * ((uint64_t)lctrCalcTotalAccuracy(pSetCigParam->sca))))); + LL_TRACE_INFO1("lctrSetCig, subIntervUsec=%d", pCisCtx->subIntervUsec); + LL_TRACE_INFO1("lctrSetCig, delayUsec=%d", pCisCtx->delayUsec); + } + + /* Calculate CIG sync delay and CIS sync delay. */ + if (pSetCigParam->packing == LL_PACKING_INTERLEAVED) + { + pCisCtxFirst = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[0].cisId); + WSF_ASSERT(pCisCtxFirst); + + pCigCtx->cigSyncDelayUsec = pCisCtxFirst->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec = pCisCtxFirst->subIntervUsec * pCisCtxFirst->nse; + pCigCtx->isoInterval = pCisCtxFirst->isoInterval; /* CISs have the same ISO interval and it is the same as CIG. */ + + for (unsigned int i = 1; i < pSetCigParam->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + uint32_t durationUs = 0; + + for (unsigned int j = 0; j < i; j++) + { + pCisCtxTemp = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[j].cisId); + durationUs += lctrCisCalcSubEvtDurationUsecSeq(pCisCtxTemp->phyMToS, pCisCtxTemp->phySToM, + pCisCtxTemp->localDataPdu.maxTxLen, pCisCtxTemp->localDataPdu.maxRxLen); + } + pCisCtx->cisSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec - durationUs; + pCisCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + } + } + else + { + /* LL_PACKING_SEQUENTIAL */ + pCisCtxFirst = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[0].cisId); + + WSF_ASSERT(pCisCtxFirst); + + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + for (unsigned int j = i; j < pSetCigParam->numCis; j++) + { + pCisCtxTemp = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[j].cisId); + + pCisCtx->cisSyncDelayUsec += (pCisCtxTemp->subIntervUsec * pCisCtxTemp->nse); + } + + pCisCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + LL_TRACE_INFO1("LL_PACKING_SEQUENTIAL, cisSyncDelayUsec=%d", pCisCtx->cisSyncDelayUsec); + } + pCigCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + pCigCtx->isoInterval = pCisCtxFirst->isoInterval; /* CISs have the same ISO interval and it is the same as CIG. */ + } + + pCigCtx->packing = pSetCigParam->packing; + pCigCtx->isValid = lctrCisMstCheckCigParams(pCigCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new CIG for testing purpose. + * + * \param pCigCtx CIS context. + * \param pSetCigParamTest CIG test parameters. + */ +/*************************************************************************************************/ +static void lctrSetCigTest(lctrCigCtx_t *pCigCtx, LlCisCigParamsTest_t *pSetCigParamTest) +{ + lctrCisCtx_t *pCisCtx, *pCisCtxTemp, *pCisCtxFirst; + + /* Calculate subevent interval for each CIS. */ + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + if (pSetCigParamTest->packing == LL_PACKING_INTERLEAVED) + { + pCisCtx->subIntervUsec = lctrCalcSubEvtDurationUsecInterTest(pSetCigParamTest); + pCisCtx->delayUsec = lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + } + else + { + /* LL_PACKING_SEQUENTIAL */ + pCisCtx->subIntervUsec = lctrCisCalcSubEvtDurationUsecSeq(pCisCtx->phyMToS, pCisCtx->phySToM, + pCisCtx->localDataPdu.maxTxLen, pCisCtx->localDataPdu.maxRxLen); + pCisCtx->delayUsec = pCisCtx->subIntervUsec; + } + + /* The formula is (2 * CIS_interva *(master_sca + slave_sca) / 1000000) */ + WSF_ASSERT((uint64_t)pCisCtx->subIntervUsec > WSF_MIN(LL_BLE_TMSS_US, LL_MATH_DIV_10E6(2 * LCTR_ISO_INT_TO_US(pCisCtx->isoInterval) * ((uint64_t)lctrCalcTotalAccuracy(pSetCigParamTest->sca))))); + } + + /* Calculate CIG sync delay and CIS sync delay. */ + if (pSetCigParamTest->packing == LL_PACKING_INTERLEAVED) + { + pCisCtxFirst = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[0].cisId); + WSF_ASSERT(pCisCtxFirst); + + pCigCtx->cigSyncDelayUsec = pCisCtxFirst->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec = pCisCtxFirst->subIntervUsec * pCisCtxFirst->nse; + pCigCtx->isoInterval = pCisCtxFirst->isoInterval; /* CISs have the same ISO interval and it is the same as CIG. */ + + for (unsigned int i = 1; i < pSetCigParamTest->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + uint32_t durationUs = 0; + + for (unsigned int j = 0; j < i; j++) + { + pCisCtxTemp = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[j].cisId); + durationUs += lctrCisCalcSubEvtDurationUsecSeq(pCisCtxTemp->phyMToS, pCisCtxTemp->phySToM, + pCisCtxTemp->localDataPdu.maxTxLen, pCisCtxTemp->localDataPdu.maxRxLen); + } + pCisCtx->cisSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec - durationUs; + pCisCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + } + } + else + { + pCisCtxFirst = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[0].cisId); + + WSF_ASSERT(pCisCtxFirst); + + /* LL_PACKING_SEQUENTIAL */ + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + pCisCtx = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[i].cisId); + + WSF_ASSERT(pCisCtx); + + for (unsigned int j = i; j < pSetCigParamTest->numCis; j++) + { + pCisCtxTemp = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[j].cisId); + + pCisCtx->cisSyncDelayUsec += (pCisCtxTemp->subIntervUsec * pCisCtxTemp->nse); + } + + pCisCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + } + pCigCtx->cigSyncDelayUsec = pCisCtxFirst->cisSyncDelayUsec; /* CIG_SYNC_DELAY = CIS_SYNC_DELAY[0] */ + pCigCtx->isoInterval = pCisCtxFirst->isoInterval; /* CISs have the same ISO interval and it is the same as CIG. */ + } + + pCigCtx->packing = pSetCigParamTest->packing; + pCigCtx->isValid = lctrCisMstCheckCigParams(pCigCtx); +} + +/*************************************************************************************************/ +/*! + * \brief Set up a new CIS or update an existing CIS for testing purpose. + * + * \param pCisCtx CIS context. + * \param pSetCigParamTest CIG parameters. + * \param pCigCisParamTest CIS parameters. + */ +/*************************************************************************************************/ +static void lctrSetCisTest(lctrCisCtx_t *pCisCtx, LlCisCigParamsTest_t *pSetCigParamTest, + LlCisCigCisParamsTest_t *pCigCisParamTest) +{ + pCisCtx->sduIntervalMToS = pSetCigParamTest->sduIntervalMToS; + pCisCtx->sduIntervalSToM = pSetCigParamTest->sduIntervalSToM; + pCisCtx->ftMToS = pSetCigParamTest->ftMToS; + pCisCtx->ftSToM = pSetCigParamTest->ftSToM; + pCisCtx->isoInterval = pSetCigParamTest->isoInterval; + pCisCtx->sca = pSetCigParamTest->sca; + pCisCtx->packing = pSetCigParamTest->packing; + pCisCtx->framing = pSetCigParamTest->framing; + + pCisCtx->cisId = pCigCisParamTest->cisId; + pCisCtx->nse = pCigCisParamTest->nse; + pCisCtx->sduSizeMToS = pCigCisParamTest->sduSizeMToS; + pCisCtx->sduSizeSToM = pCigCisParamTest->sduSizeSToM; + pCisCtx->phyMToS = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCigCisParamTest->phyMToS)); + pCisCtx->phySToM = lctrPhysBitToPhy(lctrChoosePreferredPhy(pCigCisParamTest->phySToM)); + pCisCtx->bnMToS = pCigCisParamTest->bnMToS; + pCisCtx->bnSToM = pCigCisParamTest->bnSToM; + + pCisCtx->accessAddr = lctrComputeAccessAddr(); + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + WSF_ASSERT(pCtx); + pCisCtx->crcInit = pCtx->crcInit; + pCisCtx->supTimeoutMs = pCtx->supTimeoutMs; + + pCisCtx->localDataPdu.maxTxLen = pCigCisParamTest->pduSizeMToS; + pCisCtx->localDataPdu.maxRxLen = pCigCisParamTest->pduSizeSToM; +} + +/*************************************************************************************************/ +/*! + * \brief Set CIG parameters. + * + * \param pSetCigParam CIG parameters. + * \param pCisHandles Returned CIS handles. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSetCigParam(LlCisCigParams_t *pSetCigParam, uint16_t *pCisHandles) +{ + lctrCigCtx_t *pCigCtx; + + if ((pCigCtx = lctrFindCigById(pSetCigParam->cigId)) == NULL) + { + if ((pCigCtx = lctrAllocCigCtx(pSetCigParam->cigId)) == NULL) + { + LL_TRACE_WARN0("LctrSetCigParam, there is no more CIG context"); + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + } + + if (pCigCtx->numCisEsted > 0) + { + LL_TRACE_WARN0("LctrSetCigParam, there is an established CIS"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (lmgrCisMstCb.createCisPend == TRUE) + { + LL_TRACE_WARN0("LctrSetCigParam, there is a pending CIS"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + lctrCisCtx_t *pCisCtx; + + uint8_t numEnableCis = lctrGetNumEnabledCisCtx(pSetCigParam); + + if (numEnableCis == 0) + { + /* Set up new CIS contexts. */ + if (pSetCigParam->numCis > lctrGetNumAvailCisCtx()) + { + LL_TRACE_WARN0("LctrSetCigParam, there is no more CIS context"); + return LL_ERROR_CODE_CONN_LIMIT_EXCEEDED; + } + else + { + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + pCisCtx = lctrAllocCisCtx(pCigCtx); + pCisCtx->role = LL_ROLE_MASTER; + lctrSetCis(pCisCtx, pSetCigParam, &pSetCigParam->pCisParam[i]); + pCisHandles[i] = pCisCtx->cisHandle; + } + lctrSetCig(pCigCtx, pSetCigParam); + } + } + else + { + if ((pSetCigParam->numCis - numEnableCis) > lctrGetNumAvailCisCtx()) + { + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + else + { + for (unsigned int i = 0; i < pSetCigParam->numCis; i++) + { + if ((pCisCtx = lctrFindCisById(pSetCigParam->cigId, pSetCigParam->pCisParam[i].cisId)) != NULL) + { + /* Update the context which is already set up. */ + lctrSetCis(pCisCtx, pSetCigParam, &pSetCigParam->pCisParam[i]); + } + else + { + /* Allocate new context, no allocation error, already checked. */ + pCisCtx = lctrAllocCisCtx(pCigCtx); + pCisCtx->role = LL_ROLE_MASTER; + lctrSetCis(pCisCtx, pSetCigParam, &pSetCigParam->pCisParam[i]); + } + pCisHandles[i] = pCisCtx->cisHandle; + } + lctrSetCig(pCigCtx, pSetCigParam); + } + } + + pCigCtx->roleData.mst.numCis = pSetCigParam->numCis; + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Set CIG parameters for testing purpose. + * + * \param pSetCigParamTest CIG parameters for testing. + * \param pCisHandles Returned CIS handles. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSetCigParamTest(LlCisCigParamsTest_t *pSetCigParamTest, uint16_t *pCisHandles) +{ + lctrCigCtx_t *pCigCtx; + + if ((pCigCtx = lctrFindCigById(pSetCigParamTest->cigId)) == NULL) + { + if ((pCigCtx = lctrAllocCigCtx(pSetCigParamTest->cigId)) == NULL) + { + LL_TRACE_WARN0("LctrSetCigParamTest, there is no more CIG context"); + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + } + + if (pCigCtx->numCisEsted > 0) + { + LL_TRACE_WARN0("LctrSetCigParamTest, there is an established CIS"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + lctrCisCtx_t *pCisCtx; + + uint8_t numEnableCis = lctrGetNumEnabledCisCtxTest(pSetCigParamTest); + + if (numEnableCis == 0) + { + /* Set up new CIS contexts. */ + if (pSetCigParamTest->numCis > lctrGetNumAvailCisCtx()) + { + LL_TRACE_WARN0("LctrSetCigParamTest, there is no more CIS context"); + return LL_ERROR_CODE_CONN_LIMIT_EXCEEDED; + } + else + { + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + pCisCtx = lctrAllocCisCtx(pCigCtx); + pCisCtx->role = LL_ROLE_MASTER; + lctrSetCisTest(pCisCtx, pSetCigParamTest, &pSetCigParamTest->pCisParam[i]); + pCisHandles[i] = pCisCtx->cisHandle; + } + lctrSetCigTest(pCigCtx, pSetCigParamTest); + } + } + else + { + if ((pSetCigParamTest->numCis - numEnableCis) > lctrGetNumAvailCisCtx()) + { + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + else + { + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + if ((pCisCtx = lctrFindCisById(pSetCigParamTest->cigId, pSetCigParamTest->pCisParam[i].cisId)) != NULL) + { + /* Update the context which is already set up. */ + lctrSetCisTest(pCisCtx, pSetCigParamTest, &pSetCigParamTest->pCisParam[i]); + } + else + { + /* Allocate new context, no allocation error, already checked. */ + pCisCtx = lctrAllocCisCtx(pCigCtx); + pCisCtx->role = LL_ROLE_MASTER; + lctrSetCisTest(pCisCtx, pSetCigParamTest, &pSetCigParamTest->pCisParam[i]); + } + pCisHandles[i] = pCisCtx->cisHandle; + } + lctrSetCigTest(pCigCtx, pSetCigParamTest); + } + } + + pCigCtx->roleData.mst.numCis = pSetCigParamTest->numCis; + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Remove CIG. + * + * \param cigId Identifier for CIG. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrRemoveCig(uint8_t cigId) +{ + lctrCigCtx_t *pCigCtx; + + if ((pCigCtx = lctrFindCigById(cigId)) == NULL) + { + LL_TRACE_WARN1("LctrRemoveCig, invalid CIG_ID=%d.", cigId); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + /* Return LL_ERROR_CODE_CMD_DISALLOWED if anyone of the CIS is pending or slave role in the CIG. */ + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled == TRUE) && + (pCisCtx->cigId == cigId)) + { + if (pCisCtx->role == LL_ROLE_SLAVE) + { + LL_TRACE_WARN0("LctrRemoveCig, invalid role"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (pCisCtx->isCisReqPend == TRUE) + { + LL_TRACE_WARN0("LctrRemoveCig, there is a pending CIS"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + } + + if (lctrGetNumEstCisCtxByCigCtx(pCigCtx) > 0) + { + LL_TRACE_WARN0("LctrRemoveCig, there is an established CIS"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled == TRUE) && + (pCisCtx->cigId == cigId) && + (pCisCtx->role == LL_ROLE_MASTER)) + { + lctrFreeCisCtx(pCisCtx); + } + } + + lctrFreeCigCtx(pCigCtx); + + return LL_SUCCESS; +} + + + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer controller resources for CIS master. + */ +/*************************************************************************************************/ +void LctrMstCisInit(void) +{ + /* Add reset handler. */ + lctrResetHdlrTbl[LCTR_DISP_CIS] = lctrCisMstResetHandler; + + /* Add CIS message dispatcher. */ + lctrMsgDispTbl[LCTR_DISP_CIS] = (LctrMsgDisp_t)lctrCisDisp; + + /* Add CIS function pointers */ + LctrUpdateCisChanMapFn = LctrCisUpdateChanMap; + lctrRegisterChClassHandler(lctrMstCisChClassUpdate); + + /* Add CIS event handlers. */ + lctrEventHdlrTbl[LCTR_EVENT_CIS_TX_PENDING] = lctrIsoTxPendingHandler; + lctrEventHdlrTbl[LCTR_EVENT_CIS_RX_PENDING] = lctrCisRxPendingHandler; + lctrEventHdlrTbl[LCTR_EVENT_ISO_TX_COMPLETE] = lctrIsoTxCompletedHandler; + + /* Add LLCP SM handler. */ + lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_EST] = lctrMstLlcpExecuteCisEstSm; + lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM] = lctrLlcpExecuteCisTermSm; + + lctrCisDefaults(); + LmgrMstCisInit(); + + /* Set supported features. */ + if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_1) + { + lmgrPersistCb.featuresDefault |= LL_FEAT_CIS_MASTER_ROLE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Create CIS. + * + * \param numCis Number of streams to create. + * \param pCreateCisParam CIS parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrCreateCis(uint8_t numCis, LlCisCreateCisParams_t *pCreateCisParam) +{ + /* Return error if the previous create CIS is pending. */ + if (lmgrCisMstCb.createCisPend == TRUE) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + /* Make sure handle is valid and CIS is not yet established. */ + for (unsigned int i = 0; i < numCis; i++) + { + lctrCisCtx_t *pCisCtx; + + if ((pCisCtx = lctrFindCisByHandle(pCreateCisParam->pCisHandle[i])) == NULL) + { + LL_TRACE_WARN0("LctrCreateCis, invalid CIS handle"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + if (lctrIsCisEst(pCisCtx) == TRUE) + { + LL_TRACE_WARN0("LctrCreateCis, CIS is already established"); + return LL_ERROR_CODE_ACL_CONN_ALREADY_EXISTS; + } + } + + lmgrCisMstCb.createCisPend = TRUE; + + lctrMstCreateCisPend.numCis = numCis; + /* Save the handles */ + for (unsigned int i = 0; i < numCis; i++) + { + lctrMstCreateCisPend.cisHandle[i] = pCreateCisParam->pCisHandle[i]; + lctrMstCreateCisPend.aclHandle[i] = pCreateCisParam->pAclHandle[i]; + lctrMstCreateCisPend.isCreateCisDone[i] = FALSE; + } + + /* Only start first CIS establishment procedure. */ + lctrCreateCis_t *pMsg; + + if ((pMsg = (lctrCreateCis_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = lctrMstCreateCisPend.aclHandle[0]; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_CIS_REQ; + + pMsg->cisHandle = lctrMstCreateCisPend.cisHandle[0]; + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Build a CIG operation. + * + * \param pCigCtx CIG context. + */ +/*************************************************************************************************/ +void lctrMstCisBuildCigOp(lctrCigCtx_t *pCigCtx) +{ + /* Pre-resolve common structures for efficient access. */ + BbOpDesc_t * const pOp = &pCigCtx->cigBod; + + /* When build the BOD, always setup channel use the first CIS context in the CIG. */ + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->pCisCtx = pCisCtx; + + BbBleData_t * const pBle = &pCisCtx->bleData; + BbBleMstCisEvent_t * const pCis = &pBle->op.mstCis; + + memset(pOp, 0, sizeof(BbOpDesc_t)); + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pCis, 0, sizeof(BbBleMstCisEvent_t)); + + /*** CIS context setup ***/ + + /* pFirstCisCtx->cisEvtCounter = 0; */ /* cleared in alloc. */ + /* pFirstCisCtx->txHdr.sn = 0; */ /* cleared in alloc */ + /* pFirstCisCtx->txHdr.nesn = 0; */ /* cleared in alloc */ + + /*** BLE general setup ***/ + + pBle->chan.opType = BB_BLE_OP_MST_CIS_EVENT; + + pBle->chan.chanIdx = pCisCtx->chIdx; /* Set in the lctrCisSetupChanParam. */ + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + pBle->chan.accAddr = pCisCtx->accessAddr; + pBle->chan.crcInit = pCisCtx->crcInit; + pBle->chan.txPhy = pCisCtx->phyMToS; + pBle->chan.rxPhy = pCisCtx->phySToM;; + pBle->chan.peerTxStableModIdx = TRUE; + pBle->chan.peerRxStableModIdx = TRUE; + + /* Set PHY options to mirror acl connection option. */ + pBle->chan.initTxPhyOptions = BB_PHY_OPTIONS_BLE_S8; + +#if (LL_ENABLE_TESTER) + pBle->chan.accAddrRx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.accAddrTx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.crcInitRx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitRx; + pBle->chan.crcInitTx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitTx; +#endif + + /* pBle->chan.enc.enaEncrypt = FALSE; */ /* cleared in alloc */ + /* pBle->chan.enc.enaDecrypt = FALSE; */ + pBle->chan.enc.enaAuth = TRUE; + pBle->chan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + pBle->chan.enc.pTxPktCounter = &pCisCtx->txPktCounter; + pBle->chan.enc.pRxPktCounter = &pCisCtx->rxPktCounter; + + /*** General setup ***/ + + /* pOp->minDurUsec = pFirstCisCtx->subIntervUsec * WSF_MAX(pFirstCisCtx->bnMToS, pFirstCisCtx->bnSToM); */ /* Guarantee at least Max BN */ + pOp->minDurUsec = pCigCtx->cigSyncDelayUsec; + pOp->maxDurUsec = pCigCtx->cigSyncDelayUsec; + + /* pOp->due = 0 */ /* set in lctrMstCisCigOpCommit() */ + pOp->reschPolicy = BB_RESCH_FIXED_PREFERRED; + pOp->protId = BB_PROT_BLE; + pOp->prot.pBle = pBle; + pOp->endCback = lctrMstCisCigEndOp; + pOp->abortCback = lctrMstCisCigAbortOp; + pOp->pCtx = pCigCtx; + + /*** BLE stream setup ***/ + + pCis->checkContOpCback = lctrMstCisCheckContOp; + pCis->execCback = lctrMstCisCigBeginOp; + pCis->contExecCback = lctrMstCisCigContOp; + pCis->postSubEvtCback = lctrMstCisCigPostSubEvt; + pCis->cancelCback = lctrMstCisCigCleanupOp; + pCis->txDataCback = lctrMstCisCigTxCompletion; + pCis->rxDataCback = lctrMstCisCigRxCompletion; + + /*** Commit operation ***/ + + /* Postponed in lctrMstCisCigOpCommit(). */ + pCigCtx->isBodBuilt = TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Build a CIG operation. + * + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrMstCisBuildCisData(lctrCisCtx_t *pCisCtx) +{ + BbBleData_t * const pBle = &pCisCtx->bleData; + BbBleMstCisEvent_t * const pCis = &pBle->op.mstCis; + lctrConnCtx_t * pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pCis, 0, sizeof(BbBleMstCisEvent_t)); + + /*** CIS context setup ***/ + + /* pCisCtx->cisEvtCounter = 0; */ /* cleared in alloc. */ + /* pCisCtx->txHdr.sn = 0; */ /* cleared in alloc */ + /* pCisCtx->txHdr.nesn = 0; */ /* cleared in alloc */ + + /*** BLE general setup ***/ + + pBle->chan.opType = BB_BLE_OP_MST_CIS_EVENT; + + pBle->chan.chanIdx = pCisCtx->chIdx; /* Set in the lctrCisSetupChanParam. */ + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + pBle->chan.accAddr = pCisCtx->accessAddr; + pBle->chan.crcInit = pCisCtx->crcInit; + pBle->chan.txPhy = pCisCtx->phyMToS; + pBle->chan.rxPhy = pCisCtx->phySToM;; + pBle->chan.peerTxStableModIdx = TRUE; + pBle->chan.peerRxStableModIdx = TRUE; + + /* Set PHY options to mirror acl connection option. */ + if (pConnCtx->bleData.chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) + { + /* Set PHY options to host defined behavior. */ + pBle->chan.initTxPhyOptions = pConnCtx->bleData.chan.tifsTxPhyOptions; + } + else + { + pBle->chan.initTxPhyOptions = BB_PHY_OPTIONS_BLE_S8; + } + +#if (LL_ENABLE_TESTER) + pBle->chan.accAddrRx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.accAddrTx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.crcInitRx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitRx; + pBle->chan.crcInitTx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitTx; +#endif + + /* pBle->chan.enc.enaEncrypt = FALSE; */ /* cleared in alloc */ + /* pBle->chan.enc.enaDecrypt = FALSE; */ + pBle->chan.enc.enaAuth = TRUE; + pBle->chan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + pBle->chan.enc.pTxPktCounter = &pCisCtx->txPktCounter; + pBle->chan.enc.pRxPktCounter = &pCisCtx->rxPktCounter; + + /*** BLE stream setup ***/ + + pCis->checkContOpCback = lctrMstCisCheckContOp; + pCis->execCback = lctrMstCisCigBeginOp; + pCis->contExecCback = lctrMstCisCigContOp; + pCis->postSubEvtCback = lctrMstCisCigPostSubEvt; + pCis->cancelCback = lctrMstCisCigCleanupOp; + pCis->txDataCback = lctrMstCisCigTxCompletion; + pCis->rxDataCback = lctrMstCisCigRxCompletion; +} + +/*************************************************************************************************/ +/*! + * \brief Commit a CIG operation. + * + * \param pCigCtx CIG context. + * \param pCtx ACL connection context. + * \param pCisCtx CIS connection context. + */ +/*************************************************************************************************/ +void lctrMstCisCigOpCommit(lctrCigCtx_t *pCigCtx, lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + BbOpDesc_t * const pOp = &pCigCtx->cigBod; + BbOpDesc_t *pConnBod = &pCtx->connBod; + uint32_t refTime; + + if (pCisCtx->ceRef <= pCtx->eventCounter) + { + /* Recalculate the CE ref if it is already past. */ + pCisCtx->ceRef = pCtx->eventCounter + + LL_MIN_INSTANT + 1 + /* +1 for next CE */ + pCtx->maxLatency; /* ensure slave will listen to this packet */ + + refTime = pConnBod->dueUsec + (pCisCtx->ceRef - pCtx->eventCounter) * LCTR_CONN_IND_US(pCtx->connInterval); + + pCisCtx->offsetUsec = SchRmGetOffsetUsec(LCTR_ISO_INT_TO_US(pCigCtx->isoInterval), + LCTR_GET_CIG_RM_HANDLE(pCigCtx), refTime); + } + else + { + refTime = pConnBod->dueUsec + (pCisCtx->ceRef - pCtx->eventCounter) * LCTR_CONN_IND_US(pCtx->connInterval); + } + + pOp->dueUsec = refTime + pCisCtx->offsetUsec; + + (void)SchInsertAtDueTime(pOp, lctrCisResolveConflict); /* CIS has the highest priority so scheduling will never fail. */ + + pCigCtx->isBodStarted = TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Get reference time(due time) of the CIG BOD. + * + * \param rmHandle Reservation manager handle of CIG BOD. + * \param pDurUsec Pointer to duration of the CIG BOD. + * + * \return Due time in microseconds of the CIG BOD. + */ +/*************************************************************************************************/ +uint32_t lctrGetCigRefTime(uint8_t rmHandle, uint32_t *pDurUsec) +{ + uint32_t refTime = 0; + lctrCigCtx_t *pCigCtx = LCTR_GET_CIG_RM_CTX(rmHandle); + + WSF_ASSERT(pCigCtx); + + if (pCigCtx->isBodStarted) + { + refTime = pCigCtx->cigBod.dueUsec; + if (pDurUsec) + { + *pDurUsec = pCigCtx->cigBod.minDurUsec; + } + } + + return refTime; +} + +/*************************************************************************************************/ +/*! + * \brief Create CIS procedure finishes. + * + * \param pCisCtx CIS connection context. + */ +/*************************************************************************************************/ +void lctrMstCreateCisDone(lctrCisCtx_t *pCisCtx) +{ + /* Update the create CIS pending data structure. */ + for (unsigned int i = 0; i < lctrMstCreateCisPend.numCis; i++) + { + if (pCisCtx->cisHandle == lctrMstCreateCisPend.cisHandle[i]) + { + lctrMstCreateCisPend.isCreateCisDone[i] = TRUE; + break; + } + } + + /* Continue creating next CIS. */ + for (unsigned int i = 0; i < lctrMstCreateCisPend.numCis; i++) + { + if (lctrMstCreateCisPend.isCreateCisDone[i] == FALSE) + { + lctrCreateCis_t *pMsg; + + if ((pMsg = (lctrCreateCis_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = lctrMstCreateCisPend.aclHandle[i]; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_CIS_REQ; + + pMsg->cisHandle = lctrMstCreateCisPend.cisHandle[i]; + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + return; + } + } + + /* No create CIS is pending. */ + lmgrCisMstCb.createCisPend = FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_slave.c new file mode 100644 index 00000000000..34baaddec41 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_cis_slave.c @@ -0,0 +1,416 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connected isochronous stream slave operation builder implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_iso.h" +#include "lctr_int_cis_slave.h" +#include "lctr_int_conn_slave.h" +#include "lctr_int_conn.h" +#include "lctr_int.h" +#include "sch_api.h" +#include "sch_api_ble.h" +#include "bb_api.h" +#include "pal_bb.h" +#include "wsf_assert.h" +#include "wsf_buf.h" +#include "wsf_cs.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Globals +**************************************************************************************************/ + +/************************************************************************************************** + Internal functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief CIS slave reset handler. + */ +/*************************************************************************************************/ +static void lctrSlvCisResetHandler(void) +{ + BbBleCisSlaveInit(); + BbBleCisMasterInit(); + lctrCisDefaults(); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer controller resources for CIS slave. + */ +/*************************************************************************************************/ +void LctrCisSlvInit(void) +{ + /* Add reset handler. */ + lctrResetHdlrTbl[LCTR_DISP_CIS] = lctrSlvCisResetHandler; + + /* Add connection message dispatcher. */ + if (lctrMsgDispTbl[LCTR_DISP_CIS] != NULL) + { + lctrMsgDispTbl[LCTR_DISP_CIS] = (LctrMsgDisp_t)lctrCisDisp; + } + + lctrCisDefaults(); + + /* Add connection event handlers. */ + lctrEventHdlrTbl[LCTR_EVENT_CIS_RX_PENDING] = lctrCisRxPendingHandler; + lctrEventHdlrTbl[LCTR_EVENT_ISO_TX_COMPLETE] = lctrIsoTxCompletedHandler; + + /* Add LLCP SM handler. */ + lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_EST] = lctrSlvLlcpExecuteCisEstSm; + lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM] = lctrLlcpExecuteCisTermSm; + + /* Set supported features. */ + if (pLctrRtCfg->btVer >= LL_VER_BT_CORE_SPEC_5_1) + { + lmgrPersistCb.featuresDefault |= LL_FEAT_CIS_SLAVE_ROLE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Reject CIS request. + * + * \param cisHandle CIS handle. + * \param reason Reason. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrRejectCisReq(uint16_t cisHandle, uint8_t reason) +{ + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(cisHandle); + + if (pCisCtx == NULL) + { + LL_TRACE_WARN0("LctrRejectCisReq, invalid CIS handle"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + if (pCtx == NULL) + { + LL_TRACE_WARN0("LctrRejectCisReq, invalid ACL handle"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + if (pCtx->role == LL_ROLE_MASTER) + { + LL_TRACE_WARN0("LctrRejectCisReq, invalid role"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + lctrRejCisReq_t *pMsg; + + if ((pMsg = (lctrRejCisReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = pCisCtx->aclHandle; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_CIS_REQ_REJECT; + pMsg->reason = reason; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Accept CIS request. + * + * \param cisHandle CIS handle. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrAcceptCisReq(uint16_t cisHandle) +{ + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(cisHandle); + + if (pCisCtx == NULL) + { + LL_TRACE_WARN0("LctrAcceptCisReq, invalid CIS handle"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + if (pCtx == NULL) + { + LL_TRACE_WARN0("LctrAcceptCisReq, invalid ACL handle"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + if (pCtx->role == LL_ROLE_MASTER) + { + LL_TRACE_WARN0("LctrAcceptCisReq, invalid role"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + lctrMsgHdr_t *pMsg; + + if ((pMsg = (lctrMsgHdr_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->handle = pCisCtx->aclHandle; + pMsg->dispId = LCTR_DISP_CONN; + pMsg->event = LCTR_CONN_MSG_API_CIS_REQ_ACCEPT; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Build a CIG operation. + * + * \param pCigCtx CIG context. + */ +/*************************************************************************************************/ +void lctrSlvCisBuildCigOp(lctrCigCtx_t *pCigCtx) +{ + /* Pre-resolve common structures for efficient access. */ + BbOpDesc_t * const pOp = &pCigCtx->cigBod; + + /* When build the BOD, always setup channel use the first CIS context in the CIG. */ + lctrCisCtx_t *pCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + pCigCtx->pCisCtx = pCisCtx; + + BbBleData_t * const pBle = &pCisCtx->bleData; + BbBleSlvCisEvent_t * const pCis = &pBle->op.slvCis; + + memset(pOp, 0, sizeof(BbOpDesc_t)); + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pCis, 0, sizeof(BbBleMstCisEvent_t)); + + /*** CIG context setup ***/ + + /* pCigCtx->cigEvtCounter = 0; */ /* cleared in alloc. */ + + /*** CIS context setup ***/ + + /* pCisCtx->cisEvtCounter = 0; */ /* cleared in alloc. */ + /* pCisCtx->txHdr.sn = 0; */ /* cleared in alloc */ + /* pCisCtx->txHdr.nesn = 0; */ /* cleared in alloc */ + + /*** BLE general setup ***/ + + pBle->chan.opType = BB_BLE_OP_SLV_CIS_EVENT; + + pBle->chan.chanIdx = pCisCtx->chIdx; /* Set in the lctrCisSetupChanParam. */ + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + pBle->chan.accAddr = pCisCtx->accessAddr; + pBle->chan.crcInit = pCisCtx->crcInit; + pBle->chan.txPhy = pCisCtx->phySToM; + pBle->chan.rxPhy = pCisCtx->phyMToS; + pBle->chan.peerTxStableModIdx = TRUE; + pBle->chan.peerRxStableModIdx = TRUE; + + /* Set PHY options to mirror acl connection option. */ + pBle->chan.initTxPhyOptions = BB_PHY_OPTIONS_BLE_S8; + +#if (LL_ENABLE_TESTER) + pBle->chan.accAddrRx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.accAddrTx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.crcInitRx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitRx; + pBle->chan.crcInitTx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitTx; +#endif + + /* pBle->chan.enc.enaEncrypt = FALSE; */ /* cleared in alloc */ + /* pBle->chan.enc.enaDecrypt = FALSE; */ /* cleared in alloc */ + pBle->chan.enc.enaAuth = TRUE; + pBle->chan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + pBle->chan.enc.pTxPktCounter = &pCisCtx->txPktCounter; + pBle->chan.enc.pRxPktCounter = &pCisCtx->rxPktCounter; + + /*** General setup ***/ + + pOp->minDurUsec = pCisCtx->subIntervUsec * WSF_MAX(pCisCtx->bnMToS, pCisCtx->bnSToM); /* Guarantee at least Max BN */ + pOp->maxDurUsec = pCigCtx->cigSyncDelayUsec; + + /* pOp->due = 0 */ /* set in lctrCisMstCigOpCommit() */ + pOp->reschPolicy = BB_RESCH_FIXED_PREFERRED; + pOp->protId = BB_PROT_BLE; + pOp->prot.pBle = pBle; + pOp->endCback = lctrSlvCisCigEndOp; + pOp->abortCback = lctrSlvCisCigAbortOp; + pOp->pCtx = pCigCtx; + + /*** BLE stream setup ***/ + + pCis->checkContOpCback = lctrSlvCisCheckContOp; + pCis->execCback = lctrSlvCisCigBeginOp; + pCis->contExecCback = lctrSlvCisCigContOp; + pCis->postSubEvtCback = lctrSlvCisCigPostSubEvt; + pCis->cancelCback = lctrSlvCisCigCleanupOp; + pCis->txDataCback = lctrSlvCisCigTxCompletion; + pCis->rxDataCback = lctrSlvCisCigRxCompletion; + + /*** Commit operation ***/ + + /* Postponed in lctrCisMstCigOpCommit(). */ + pCigCtx->isBodBuilt = TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Build a CIG operation. + * + * \param pCisCtx CIG context. + */ +/*************************************************************************************************/ +void lctrSlvCisBuildCisData(lctrCisCtx_t *pCisCtx) +{ + BbBleData_t * const pBle = &pCisCtx->bleData; + BbBleSlvCisEvent_t * const pCis = &pBle->op.slvCis; + lctrConnCtx_t * pConnCtx = LCTR_GET_CONN_CTX(pCisCtx->aclHandle); + + memset(pBle, 0, sizeof(BbBleData_t)); + memset(pCis, 0, sizeof(BbBleMstCisEvent_t)); + + /*** CIS context setup ***/ + + /* pCisCtx->cisEvtCounter = 0; */ /* cleared in alloc. */ + /* pCisCtx->txHdr.sn = 0; */ /* cleared in alloc */ + /* pCisCtx->txHdr.nesn = 0; */ /* cleared in alloc */ + + /*** BLE general setup ***/ + + pBle->chan.opType = BB_BLE_OP_SLV_CIS_EVENT; + + pBle->chan.chanIdx = pCisCtx->chIdx; /* Set in the lctrCisSetupChanParam. */ + pBle->chan.txPower = pLctrRtCfg->defTxPwrLvl; + pBle->chan.accAddr = pCisCtx->accessAddr; + pBle->chan.crcInit = pCisCtx->crcInit; + pBle->chan.txPhy = pCisCtx->phySToM; + pBle->chan.rxPhy = pCisCtx->phyMToS; + pBle->chan.peerTxStableModIdx = TRUE; + pBle->chan.peerRxStableModIdx = TRUE; + + /* Set PHY options to mirror acl connection option. */ + if (pConnCtx->bleData.chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) + { + /* Set PHY options to host defined behavior. */ + pBle->chan.initTxPhyOptions = pConnCtx->bleData.chan.tifsTxPhyOptions; + } + else + { + pBle->chan.initTxPhyOptions = BB_PHY_OPTIONS_BLE_S8; + } + +#if (LL_ENABLE_TESTER) + pBle->chan.accAddrRx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.accAddrTx = pCisCtx->accessAddr ^ llTesterCb.cisAccessAddrRx; + pBle->chan.crcInitRx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitRx; + pBle->chan.crcInitTx = pCisCtx->crcInit ^ llTesterCb.cisCrcInitTx; +#endif + + /* pBle->chan.enc.enaEncrypt = FALSE; */ /* cleared in alloc */ + /* pBle->chan.enc.enaDecrypt = FALSE; */ /* cleared in alloc */ + pBle->chan.enc.enaAuth = TRUE; + pBle->chan.enc.nonceMode = PAL_BB_NONCE_MODE_EXT64_CNTR; + pBle->chan.enc.pTxPktCounter = &pCisCtx->txPktCounter; + pBle->chan.enc.pRxPktCounter = &pCisCtx->rxPktCounter; + + /*** BLE stream setup ***/ + + pCis->checkContOpCback = lctrSlvCisCheckContOp; + pCis->execCback = lctrSlvCisCigBeginOp; + pCis->contExecCback = lctrSlvCisCigContOp; + pCis->postSubEvtCback = lctrSlvCisCigPostSubEvt; + pCis->cancelCback = lctrSlvCisCigCleanupOp; + pCis->txDataCback = lctrSlvCisCigTxCompletion; + pCis->rxDataCback = lctrSlvCisCigRxCompletion; +} + +/*************************************************************************************************/ +/*! + * \brief Commit a CIG operation. + * + * \param pCigCtx CIG context. + * \param pCtx ACL Context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +void lctrSlvCisCigOpCommit(lctrCigCtx_t *pCigCtx, lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + BbOpDesc_t * const pOp = &pCigCtx->cigBod; + /* When commit the BOD, always setup channel use the first CIS context in the CIG. */ + lctrCisCtx_t *pFirstCisCtx = lctrCisGetHeadCis(&pCigCtx->list); + BbBleData_t * const pBle = &pFirstCisCtx->bleData; + BbBleSlvCisEvent_t * const pCis = &pBle->op.slvCis; + + pCigCtx->roleData.slv.totalAcc = pCtx->data.slv.totalAcc; + + pCigCtx->roleData.slv.anchorPointUsec = pCtx->data.slv.anchorPointUsec + LCTR_CONN_IND_US(pCtx->connInterval) + pCisCtx->data.slv.anchorOffsetUsec; + + /* Add WW to the offset. */ + const uint32_t wwOffsetUsec = lctrCalcWindowWideningUsec(pCisCtx->data.slv.anchorOffsetUsec, pCigCtx->roleData.slv.totalAcc); + pOp->dueUsec = pCigCtx->roleData.slv.anchorPointUsec - wwOffsetUsec; + pOp->minDurUsec += (wwOffsetUsec << 1); + + /*** BLE CIS setup ***/ + + pCis->rxSyncDelayUsec = (wwOffsetUsec << 1) + 1; /* rounding compensation when computing reqEndTs */ + + /*** Commit operation ***/ + + const uint32_t ceDurUsec = pOp->minDurUsec; + const uint32_t ceSyncDlyUsec = pCis->rxSyncDelayUsec; + + while (TRUE) + { + if (SchInsertAtDueTime(pOp, lctrCisResolveConflict)) + { + LL_TRACE_INFO1(" >>> CIS established, cisHandle=%u <<<", pCisCtx->cisHandle); + LL_TRACE_INFO1(" isoInterval=%u", LCTR_ISO_INT_TO_US(pCigCtx->isoInterval)); + LL_TRACE_INFO1(" dueUsec=%u", pOp->dueUsec); + pCigCtx->isBodStarted = TRUE; + break; + } + + LL_TRACE_WARN1("!!! Establish CIS schedule conflict handle=%u", LCTR_GET_CONN_HANDLE(pCtx)); + + pFirstCisCtx->cisEvtCounter++; + pBle->chan.chanIdx = LmgrSelectNextChannel(&pCisCtx->chanParam, pFirstCisCtx->cisEvtCounter, 0, TRUE); + pCisCtx->nextSubEvtChanIdx = LmgrSelectNextSubEvtChannel(&pCisCtx->chanParam); + + /* Initial eventCounter starts at 0; equivalent to unsynchronized intervals. */ + uint32_t unsyncTimeUsec = LCTR_ISO_INT_TO_US(pCigCtx->isoInterval * pFirstCisCtx->cisEvtCounter); + uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pCtx->data.slv.totalAcc); + + /* Advance to next interval. */ + pOp->dueUsec = pCigCtx->roleData.slv.anchorPointUsec + unsyncTimeUsec - wwTotalUsec; + pOp->minDurUsec = ceDurUsec + wwTotalUsec; + pCis->rxSyncDelayUsec = ceSyncDlyUsec + (wwTotalUsec << 1); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn.c index b3e7e61e2ba..766c5170ec7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller data path implementation file. + * \file + * + * \brief Link layer controller data path implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,6 +26,8 @@ #include "lctr_pdu_conn.h" #include "lmgr_api_conn.h" #include "ll_math.h" +#include "ll_api.h" +#include "pal_radio.h" #include "wsf_assert.h" #include "wsf_cs.h" #include "wsf_math.h" @@ -88,6 +91,39 @@ lctrLlcpEh_t lctrStorePeriodicSyncTrsfFn = NULL; /*! \brief Pointer to lctrReceivePeriodicSyncInd function. */ lctrLlcpEh_t lctrReceivePeriodicSyncIndFn = NULL; +/*! \brief Power monitoring scheme action table. */ +lctrPcMonAct_t lctrPcActTbl[LCTR_PC_MONITOR_SCHEME_TOTAL]; + +/*! \brief Pointer to lctrSendPowerChangeInd function. */ +lctrPcPowInd_t lctrSendPowerChangeIndCback = NULL; + +/*! \brief Pointer to lctrNotifyPowerReportInd function. */ +lctrPcNotifyPwr_t lctrNotifyPowerReportIndCback = NULL; + +/*************************************************************************************************/ +/*! + * \brief Return PHYs supported by LL. + * + * \return Bit field of supported PHYs. + */ +/*************************************************************************************************/ +static uint8_t llGetSupportedPhys(void) +{ + uint8_t supportPhyBits = LL_PHYS_LE_1M_BIT; + + if ((lmgrCb.features & LL_FEAT_LE_2M_PHY)) + { + supportPhyBits |= LL_PHYS_LE_2M_BIT; + } + + if ((lmgrCb.features & LL_FEAT_LE_CODED_PHY)) + { + supportPhyBits |= LL_PHYS_LE_CODED_BIT; + } + + return supportPhyBits; +} + /*************************************************************************************************/ /*! * \brief Initialize the connection memory resources. @@ -146,8 +182,6 @@ uint16_t LctrInitConnMem(uint8_t *pFreeMem, uint32_t freeMemSize) * \brief Assign vendor specific PDU handlers. * * \param pHdlrs Static definition for VS handlers. - * - * \return None. */ /*************************************************************************************************/ void LctrVsConnInit(const LctrVsHandlers_t *pHdlrs) @@ -166,16 +200,35 @@ void LctrVsConnInit(const LctrVsHandlers_t *pHdlrs) /*************************************************************************************************/ uint8_t LctrValidateConnSpec(const LlConnSpec_t *pConnSpec) { - if ((pConnSpec->connIntervalMin < LL_MIN_CONN_INTERVAL) || - (pConnSpec->connIntervalMax > LL_MAX_CONN_INTERVAL) || - (pConnSpec->connIntervalMin > pConnSpec->connIntervalMax) || - /* (pConnSpec->connLatency < connLatencyMin) || */ - (pConnSpec->connLatency > LL_MAX_CONN_LATENCY) || - (pConnSpec->supTimeout < LL_MIN_SUP_TIMEOUT) || - (pConnSpec->supTimeout > LL_MAX_SUP_TIMEOUT) || - (pConnSpec->supTimeout <= ((1 + pConnSpec->connLatency) * pConnSpec->connIntervalMax >> 2))) - { - LL_TRACE_WARN0("LctrValidateConnSpec: invalid parameters"); + /* Connection interval. */ + if ((LL_API_PARAM_CHECK == 1) && + ((pConnSpec->connIntervalMin > pConnSpec->connIntervalMax) || + (pConnSpec->connIntervalMax < HCI_CONN_INTERVAL_MIN) || + (pConnSpec->connIntervalMin < HCI_CONN_INTERVAL_MIN) || + (pConnSpec->connIntervalMax > HCI_CONN_INTERVAL_MAX) || + (pConnSpec->connIntervalMin > HCI_CONN_INTERVAL_MAX) )) + { + LL_TRACE_WARN0("LctrValidateConnSpec: Connection interval is invalid"); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + /* Connection latency. */ + if ((LL_API_PARAM_CHECK == 1) && + ((pConnSpec->connLatency > HCI_CONN_LATENCY_MAX))) + { + LL_TRACE_WARN0("LctrValidateConnSpec: connection latency is invalid"); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + /* Supervision timeout. */ + uint32_t supTimeoutMin = ((uint32_t) pConnSpec->connLatency + 1) * LCTR_CONN_IND_US((uint32_t) pConnSpec->connIntervalMax) * 2; + uint32_t supTimeoutUs = LCTR_SUP_TIMEOUT_VAL_TO_US((uint32_t) pConnSpec->supTimeout); + if ((LL_API_PARAM_CHECK == 1) && + ((supTimeoutUs <= supTimeoutMin) || + (pConnSpec->supTimeout < HCI_SUP_TIMEOUT_MIN) || + (pConnSpec->supTimeout > HCI_SUP_TIMEOUT_MAX))) + { + LL_TRACE_WARN0("LctrValidateConnSpec: supervision timeout is invalid"); return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } @@ -241,8 +294,6 @@ bool_t LctrIsProcActPended(uint16_t handle, uint8_t event) * \param handle Connection handle. * \param pMode New encryption mode. * - * \return None. - * * Get the encryption mode used by a connection. */ /*************************************************************************************************/ @@ -294,8 +345,6 @@ bool_t LctrSetEncMode(uint16_t handle, const LlEncMode_t *pMode) * \param flags Flags. * \param enable TRUE to set flags or FALSE to clear flags. * - * \return None. - * * Set mode flags governing LL operations of a given connection. */ /*************************************************************************************************/ @@ -371,7 +420,7 @@ lctrConnCtx_t *lctrAllocConnCtx(void) pCtx->localDataPdu.maxRxLen = WSF_MIN(LCTR_MAX_DATA_LEN_MAX, pLctrRtCfg->maxAclLen); pCtx->localDataPdu.maxTxTime = lmgrConnCb.maxTxTime; /* Limit with absolute time. lctrSendDataLengthPdu() limits time by PHY capability. */ - pCtx->localDataPdu.maxRxTime = LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->localDataPdu.maxRxLen); + pCtx->localDataPdu.maxRxTime = LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->localDataPdu.maxRxLen, TRUE); pCtx->effDataPdu.maxTxLen = LL_MAX_DATA_LEN_MIN; pCtx->effDataPdu.maxRxLen = LL_MAX_DATA_LEN_MIN; pCtx->effDataPdu.maxTxTime = LL_MAX_DATA_TIME_MIN; @@ -407,6 +456,18 @@ lctrConnCtx_t *lctrAllocConnCtx(void) pLctrVsHdlrs->connSetup(connIdx); } + /* Power control initialization. */ + if (pCtx->usedFeatSet & LL_FEAT_POWER_CONTROL_REQUEST) + { + pCtx->powerMonitorScheme = LCTR_PC_MONITOR_AUTO; + pCtx->monitoringState = LCTR_PC_MONITOR_ENABLED; + pCtx->pclMonitorParam.autoMonitor.highThreshold = LCTR_RSSI_HIGH_THRESHOLD; + pCtx->pclMonitorParam.autoMonitor.lowThreshold = LCTR_RSSI_LOW_THRESHOLD; + pCtx->pclMonitorParam.autoMonitor.minTimeSpent = LCTR_PC_MIN_TIME; + pCtx->pclMonitorParam.autoMonitor.requestVal = LCTR_PC_REQUEST_VAL; + pCtx->pclMonitorParam.autoMonitor.curTimeSpent = 0; + } + LmgrIncResetRefCount(); lmgrCb.numConnEnabled++; @@ -425,8 +486,6 @@ lctrConnCtx_t *lctrAllocConnCtx(void) * \brief Free a connection context. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrFreeConnCtx(lctrConnCtx_t *pCtx) @@ -537,8 +596,6 @@ uint8_t lctrSelectNextDataChannel(lctrConnCtx_t *pCtx, uint16_t numSkip) * \brief Build channel remapping table. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrBuildRemapTable(lctrConnCtx_t *pCtx) @@ -562,8 +619,6 @@ void lctrBuildRemapTable(lctrConnCtx_t *pCtx) /*************************************************************************************************/ /*! * \brief Tx data completed task event handler. - * - * \return None. */ /*************************************************************************************************/ void lctrConnTxCompletedHandler(void) @@ -611,8 +666,6 @@ void lctrConnTxCompletedHandler(void) /*************************************************************************************************/ /*! * \brief Rx data pending task event handler. - * - * \return None. */ /*************************************************************************************************/ void lctrConnRxPendingHandler(void) @@ -760,8 +813,6 @@ void lctrConnRxPendingHandler(void) * \brief Transmit ACL data path. * * \param pAclBuf ACL buffer. - * - * \return None. */ /*************************************************************************************************/ void LctrTxAcl(uint8_t *pAclBuf) @@ -772,7 +823,7 @@ void LctrTxAcl(uint8_t *pAclBuf) lctrUnpackAclHdr(&aclHdr, pAclBuf); - /*** Assemble data PDU. ***/ + /*** Resolve Connection context. ***/ if (aclHdr.connHandle >= pLctrRtCfg->maxConn) { @@ -815,7 +866,7 @@ void LctrTxAcl(uint8_t *pAclBuf) if ((aclHdr.pktBound == LCTR_PB_START_NON_AUTO_FLUSH) && (aclHdr.len == 0)) { pCtx->forceStartPdu = TRUE; /* If this was supposed to be the start fragment, make the next packet a start fragment. */ - LL_TRACE_INFO0("Next ACL header will be forced to a start fragment."); + LL_TRACE_INFO0("Next ACL header will be forced to a start fragment"); } WsfMsgFree(pAclBuf); lmgrPersistCb.sendCompCback(aclHdr.connHandle, 1); @@ -873,8 +924,6 @@ uint8_t *LctrRxAcl(void) * * \param numBufs Number of completed packets. * - * \return None. - * * Indicate that received ACL data buffer has been deallocated. */ /*************************************************************************************************/ @@ -944,6 +993,31 @@ int8_t LctrGetRssi(uint16_t handle) return pLctrConnTbl[handle].rssi; } +/*************************************************************************************************/ +/*! + * \brief Get connection's TX power level for the selected phy. + * + * \param handle Connection handle. + * \param phy PHY. + * + * \return Transmit power level. + */ +/*************************************************************************************************/ +int8_t LctrGetPhyTxPowerLevel(uint16_t handle, uint8_t phy) +{ + lctrConnCtx_t * pCtx = LCTR_GET_CONN_CTX(handle); + uint8_t option = BB_PHY_OPTIONS_BLE_S8; + + if (phy == LL_PC_PHY_CODED_S2) + { + phy = LL_PHY_LE_CODED; + option = BB_PHY_OPTIONS_BLE_S2; + } + + int8_t txPower = LCTR_GET_TXPOWER(pCtx, phy, option); + return (txPower == LL_PWR_CTRL_TXPOWER_UNMANAGED) ? 0 : txPower; +} + /*************************************************************************************************/ /*! * \brief Get the transmit power level of a connection. @@ -960,17 +1034,121 @@ int8_t LctrGetTxPowerLevel(uint16_t handle) /*************************************************************************************************/ /*! - * \brief Set the transmit power level of a connection. + * \brief Set the transmit power level of a connection (all PHYs). * * \param handle Connection handle. * \param level Transmit power level. - * - * \return None. */ /*************************************************************************************************/ void LctrSetTxPowerLevel(uint16_t handle, int8_t level) { - pLctrConnTbl[handle].bleData.chan.txPower = level; + lctrConnCtx_t * pCtx = LCTR_GET_CONN_CTX(handle); + BbBleData_t * pBle = &pCtx->bleData; + int8_t txPhyPwr = pBle->chan.txPower; + int8_t txPwrOld[LL_PC_PHY_TOTAL]; + memcpy(txPwrOld, pCtx->phyTxPower, LL_PC_PHY_TOTAL); + int8_t adjustedLevel = PalRadioGetActualTxPower(level, FALSE); + + if (adjustedLevel != level) + { + LL_TRACE_WARN2("Transmit Power set to %d instead of %d, due to hardware limitations.", adjustedLevel, level); + } + + pBle->chan.txPower = adjustedLevel; + memset(pCtx->phyTxPower, adjustedLevel, LL_PC_PHY_TOTAL); + + /* If supported, notify peer of power change on currently transmitting PHY. */ + if ((pCtx->state == LCTR_CONN_STATE_ESTABLISHED_READY) && + (txPhyPwr != adjustedLevel) && + (pCtx->usedFeatSet & LL_FEAT_POWER_CHANGE_IND) && + lctrSendPowerChangeIndCback) + { + lctrSendPowerChangeIndCback(pCtx, pBle->chan.txPhy, adjustedLevel - txPhyPwr, adjustedLevel, FALSE); + } + + /* If enabled, notify host of power change on affected PHYs. */ + if (pCtx->powerRptLocal) + { + int phy; + for (phy = 0; phy < LL_PC_PHY_TOTAL; phy++) + { + if (txPwrOld[phy] != adjustedLevel) + { + if (lctrNotifyPowerReportIndCback) + { + lctrNotifyPowerReportIndCback(pCtx, LL_POWER_REPORT_REASON_LOCAL, phy, adjustedLevel, + lctrGetPowerLimits(adjustedLevel), + adjustedLevel - txPwrOld[phy]); + } + } + } + } + +} + +/*************************************************************************************************/ +/*! + * \brief Set the transmit power level of a connection. + * + * \param handle Connection handle. + * \param level Transmit power level. + * \param phy PHY to set power level for. + */ +/*************************************************************************************************/ +void LctrSetPhyTxPowerLevel(uint16_t handle, int8_t level, uint8_t phy) +{ + lctrConnCtx_t * pCtx = LCTR_GET_CONN_CTX(handle); + BbBleData_t * pBle = &pCtx->bleData; + int8_t txPwrOld = pBle->chan.txPower; + int8_t adjustedLevel; + int8_t delta; + + /* Not specifying a PHY will set the current transmitting PHY. */ + if (phy == LL_PHY_NONE) + { + phy = pBle->chan.txPhy; + } + + adjustedLevel = PalRadioGetActualTxPower(level, FALSE); + + if (adjustedLevel != level) + { + LL_TRACE_WARN2("Transmit Power set to %d instead of %d, due to hardware limitations.", adjustedLevel, level); + } + + delta = adjustedLevel - txPwrOld; + if (delta == 0) + { + return; + } + + if (phy == pBle->chan.txPhy) + { + pBle->chan.txPower = adjustedLevel; + + /* If supported, notify peer of power change. */ + if ((pCtx->state == LCTR_CONN_STATE_ESTABLISHED_READY) && + (txPwrOld != adjustedLevel) && + (pCtx->usedFeatSet & LL_FEAT_POWER_CHANGE_IND) && + lctrSendPowerChangeIndCback) + { + lctrSendPowerChangeIndCback(pCtx, pBle->chan.txPhy, adjustedLevel - txPwrOld, adjustedLevel, FALSE); + } + } + + LCTR_SET_TXPOWER(pCtx, phy, adjustedLevel); + + + /* If enabled, notify host of power change. */ + if (pCtx->powerRptLocal) + { + if (lctrNotifyPowerReportIndCback) + { + lctrNotifyPowerReportIndCback(pCtx, LL_POWER_REPORT_REASON_LOCAL, pBle->chan.txPhy, adjustedLevel, + lctrGetPowerLimits(pBle->chan.txPower), + delta); + } + } } /*************************************************************************************************/ @@ -998,9 +1176,6 @@ uint64_t LctrGetChannelMap(uint16_t handle) /*************************************************************************************************/ uint64_t LctrGetUsedFeatures(uint16_t handle) { -// LL_TRACE_INFO1("LctrGetUsedFeatures, lmgrCb.features=%x", lmgrCb.features); -// LL_TRACE_INFO1("LctrGetUsedFeatures, pLctrConnTbl[handle].usedFeatSet=%x", pLctrConnTbl[handle].usedFeatSet); - return pLctrConnTbl[handle].usedFeatSet; } @@ -1079,8 +1254,6 @@ bool_t LctrIsWaitingForReply(uint16_t handle, uint8_t reply) * * \param pCtx Connection context. * \param event Connection event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendConnMsg(lctrConnCtx_t *pCtx, uint8_t event) @@ -1247,12 +1420,12 @@ uint8_t lctrComputeSca(void) /*************************************************************************************************/ /*! - * \brief Get reference time(due time) of the connection handle. + * \brief Get reference time (due time) of the connection handle. * * \param connHandle Connection handle. * \param pDurUsec Pointer to duration of the connection BOD. * - * \return Due time in BB ticks of the connection handle. + * \return Due time in microseconds of the connection handle. */ /*************************************************************************************************/ uint32_t lctrGetConnRefTime(uint8_t connHandle, uint32_t *pDurUsec) @@ -1262,7 +1435,7 @@ uint32_t lctrGetConnRefTime(uint8_t connHandle, uint32_t *pDurUsec) if (pCtx->enabled && (pCtx->bleData.chan.opType == BB_BLE_OP_MST_CONN_EVENT)) { - refTime = pCtx->connBod.due; + refTime = pCtx->connBod.dueUsec; if (pDurUsec) { *pDurUsec = pCtx->connBod.minDurUsec; @@ -1291,12 +1464,12 @@ uint32_t lctrConnGetAnchorPoint(lctrConnCtx_t *pCtx, uint16_t ceCounter) if ((uint16_t)(ceCounter - pCtx->eventCounter) < (uint16_t)LCTR_MAX_INSTANT) /* ceCounter is in the future. */ { numCe = ceCounter - pCtx->eventCounter; - return (pCtx->connBod.due + BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval * numCe))); + return pCtx->connBod.dueUsec + LCTR_CONN_IND_US(pCtx->connInterval * numCe); } else { numCe = pCtx->eventCounter - ceCounter; - return (pCtx->connBod.due - BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval * numCe))); + return pCtx->connBod.dueUsec - LCTR_CONN_IND_US(pCtx->connInterval * numCe); } } else @@ -1304,12 +1477,12 @@ uint32_t lctrConnGetAnchorPoint(lctrConnCtx_t *pCtx, uint16_t ceCounter) if ((uint16_t)(ceCounter - (pCtx->data.slv.lastActiveEvent - 1)) < (uint16_t)LCTR_MAX_INSTANT) /* ceCounter is in the future. */ { numCe = ceCounter - (pCtx->data.slv.lastActiveEvent - 1); - return (pCtx->data.slv.anchorPoint + BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval * numCe))); + return pCtx->data.slv.anchorPointUsec + LCTR_CONN_IND_US(pCtx->connInterval * numCe); } else { numCe = (pCtx->data.slv.lastActiveEvent - 1) - ceCounter; - return (pCtx->data.slv.anchorPoint - BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval * numCe))); + return pCtx->data.slv.anchorPointUsec - LCTR_CONN_IND_US(pCtx->connInterval * numCe); } } } @@ -1332,3 +1505,146 @@ bool_t LctrIsCisEnabled(uint16_t handle) return FALSE; } + + +/*************************************************************************************************/ +/*! + * \brief Set up transmit levels. + * + * \param pCtx Connection Context. + */ +/*************************************************************************************************/ +void lctrInitPhyTxPower(lctrConnCtx_t *pCtx) +{ + /* All transmit powers start unmanaged or unavailable. */ + uint8_t supportedPhys = llGetSupportedPhys(); + supportedPhys |= (supportedPhys & LL_PHYS_LE_CODED_BIT) ? LL_PC_CODED_S2_BIT : 0; + + uint8_t phyIdx = 0; + for (uint8_t phy = LL_PC_1M_BIT; phy <= LL_PC_MAX_BIT; phy = phy << 1) + { + if (supportedPhys & phy) + { + pCtx->phyTxPower[phyIdx++] = LL_PWR_CTRL_TXPOWER_UNMANAGED; + } + else + { + pCtx->phyTxPower[phyIdx++] = LL_PWR_CTRL_TXPOWER_UNAVAILABLE; + } + } + + /* Peer transmit power will start as unavailable until we know it through a remote read or request. */ + pCtx->peerTxPower = LL_PWR_CTRL_TXPOWER_UNAVAILABLE; +} + +/*************************************************************************************************/ +/*! + * \brief Set transmit power reporting parameters. + * + * \param handle Connection handle. + * \param enableLocal Enable local txPower change reporting. + * \param enableRemote Enable remote txPower change reporting. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrSetTxPowerReporting(uint16_t handle, uint8_t enableLocal, uint8_t enableRemote) +{ + lctrConnCtx_t * pCtx = LCTR_GET_CONN_CTX(handle); + + pCtx->powerRptLocal = enableLocal; + pCtx->powerRptRemote = enableRemote; + + if (enableRemote) + { + pCtx->controllerInitRead = TRUE; + lctrMsgPwrCtrlReq_t *pMsg; + if ((pMsg = (lctrMsgPwrCtrlReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = LCTR_GET_CONN_HANDLE(pCtx); + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_PWR_CTRL_REQ; + pMsg->delta = 0; + pMsg->phy = pCtx->bleData.chan.rxPhy + ((pCtx->bleData.chan.rxPhy == BB_PHY_BLE_CODED) && (pCtx->bleData.chan.initTxPhyOptions == BB_PHY_OPTIONS_BLE_S2)) ? 1 : 0; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Set enable state for power monitoring. + * + * \param handle Handle identifier for connection. + * \param enable Enable status for power monitor. + * + * \return Status error code. + * + * \note Path loss must be disabled. + */ +/*************************************************************************************************/ +uint8_t lctrSetPowerMonitorEnable(uint16_t handle, bool_t enable) +{ + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(handle); + + if (!(pCtx->usedFeatSet & LL_FEAT_POWER_CONTROL_REQUEST)) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if ((pCtx->powerMonitorScheme == LCTR_PC_MONITOR_PATH_LOSS) && + (pCtx->monitoringState == LCTR_PC_MONITOR_ENABLED)) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + pCtx->powerMonitorScheme = LCTR_PC_MONITOR_AUTO; + pCtx->monitoringState = enable; + pCtx->pclMonitorParam.autoMonitor.highThreshold = LCTR_RSSI_HIGH_THRESHOLD; + pCtx->pclMonitorParam.autoMonitor.lowThreshold = LCTR_RSSI_LOW_THRESHOLD; + pCtx->pclMonitorParam.autoMonitor.minTimeSpent = LCTR_PC_MIN_TIME; + pCtx->pclMonitorParam.autoMonitor.requestVal = LCTR_PC_REQUEST_VAL; + pCtx->pclMonitorParam.autoMonitor.curTimeSpent = 0; + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Get power limit bit of specified txPower. + * + * \param txPower Current transmit power. + * + * \return Limit status of txPower + */ +/*************************************************************************************************/ +uint8_t lctrGetPowerLimits(int8_t txPower) +{ + int8_t min; + int8_t max; + +#if (LL_ENABLE_TESTER == TRUE) + if (llTesterCb.powerLimits) + { + return llTesterCb.powerLimits; + } +#endif + + PalRadioGetSupTxPower(&min, &max); + + if (txPower == min) + { + return LL_PWR_CONTROL_LIMIT_MIN_BIT; + } + else if (txPower == max) + { + return LL_PWR_CONTROL_LIMIT_MAX_BIT; + } + else + { + return 0; + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_cs2.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_cs2.c index 643d72e755b..0ce66da6378 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_cs2.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_cs2.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller data path implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller data path implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -119,8 +120,6 @@ uint8_t lctrSelectNextChannel2(lctrConnCtx_t *pCtx, uint16_t numSkip) /*************************************************************************************************/ /*! * \brief Initialize the channel selection 2 resources. - * - * \return None. */ /*************************************************************************************************/ void LctrChannelSelection2Init(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_data.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_data.c index eeb4b6af8df..47d2ae670aa 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_data.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_data.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller data path implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller data path implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -40,10 +41,14 @@ Macros **************************************************************************************************/ -#define LCTR_DATA_TX_PDU_START_OFFSET 0 /*!< Data PDU start offset in a buffer. */ +/*! \brief Data PDU start offset in a buffer. */ +#define LCTR_DATA_TX_PDU_START_OFFSET 0 -#define LCTR_FRAG_HDR_MAX_LEN LL_DATA_HDR_LEN /*!< Fragment header maximum length. */ -#define LCTR_FRAG_TRL_MAX_LEN LL_DATA_MIC_LEN /*!< Fragment trailer maximum length. */ +/*! \brief Fragment header maximum length. */ +#define LCTR_FRAG_HDR_MAX_LEN LL_DATA_HDR_LEN + +/*! \brief Fragment trailer maximum length. */ +#define LCTR_FRAG_TRL_MAX_LEN LL_DATA_MIC_LEN /************************************************************************************************** Data Types @@ -96,8 +101,6 @@ static wsfHandlerId_t lctrTxCompBufHandlerId; * latency is not zero and there is data to send. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrCheckAbortSlvLatency(lctrConnCtx_t *pCtx) @@ -110,11 +113,11 @@ static void lctrCheckAbortSlvLatency(lctrConnCtx_t *pCtx) if (pCtx->maxLatency) { - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - uint32_t connInterval = BB_US_TO_BB_TICKS(LCTR_CONN_IND_US(pCtx->connInterval)); + const uint32_t curTime = PalBbGetCurrentTime(); + uint32_t connIntervalUsec = LCTR_CONN_IND_US(pCtx->connInterval); BbOpDesc_t *pOp = &pCtx->connBod; - if (((pOp->due - curTime) > connInterval) && ((pOp->due - curTime) < LCTR_SCH_MAX_SPAN)) + if (BbGetTargetTimeDelta(pOp->dueUsec, curTime) > connIntervalUsec) { /* If the connection BOD is due in the future and after the next immediate anchor point, * set the flag to adjust the connection BOD later. */ @@ -247,8 +250,6 @@ static uint16_t lctrMaxNumBytesWithinUsecCoded(uint16_t timeUsec) * * \param pCtx Connection context. * \param txPhys Transmit PHYs for PHY update in progress. - * - * \return None. */ /*************************************************************************************************/ void lctrSetPacketTimeRestriction(lctrConnCtx_t *pCtx, uint8_t txPhys) @@ -261,8 +262,6 @@ void lctrSetPacketTimeRestriction(lctrConnCtx_t *pCtx, uint8_t txPhys) * \brief Remove packet time restriction. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrRemovePacketTimeRestriction(lctrConnCtx_t *pCtx) @@ -289,16 +288,16 @@ static inline uint16_t lctrGetMaxConnDurationUsec(uint8_t phy, uint16_t maxLen, { default: case BB_PHY_BLE_1M: - maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(maxLen), maxTime); + maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(maxLen, TRUE), maxTime); break; case BB_PHY_BLE_2M: - maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(maxLen), maxTime); + maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(maxLen, TRUE), maxTime); break; case BB_PHY_BLE_CODED: /* maximum time may be less than minimum packet for coded PHY */ - maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(maxLen), + maxDur = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(maxLen, TRUE), WSF_MAX(maxTime, - LL_DATA_LEN_TO_TIME_CODED_S8(LL_MAX_DATA_LEN_MIN))); + LL_DATA_LEN_TO_TIME_CODED_S8(LL_MAX_DATA_LEN_MIN, TRUE))); break; } @@ -385,7 +384,7 @@ uint16_t lctrTxFragLen(lctrConnCtx_t *pCtx) * \return A Tx buffer descriptor, NULL if allocation fails. */ /*************************************************************************************************/ -static lctrTxBufDesc_t *lctrAllocTxBufDesc(void) +static lctrTxBufDesc_t *lctrAllocConnTxBufDesc(void) { uint8_t *pElem; @@ -404,11 +403,9 @@ static lctrTxBufDesc_t *lctrAllocTxBufDesc(void) * \brief Free a Tx buffer descriptor. * * \param pDesc Pointer to a Tx buffer descriptor. - * - * \return None. */ /*************************************************************************************************/ -static void lctrFreeTxBufDesc(lctrTxBufDesc_t *pDesc) +static void lctrFreeConnTxBufDesc(lctrTxBufDesc_t *pDesc) { uint8_t *pElem = (uint8_t *)pDesc; pElem -= (2 * sizeof(uint32_t)); /* recover header */ @@ -423,8 +420,6 @@ static void lctrFreeTxBufDesc(lctrTxBufDesc_t *pDesc) * \param pCtx Connection context. * \param pAclHdr ACL header. * \param pBuf Buffer to pack the Data PDU header. - * - * \return None. */ /*************************************************************************************************/ static void lctrAssembleDataPdu(lctrConnCtx_t *pCtx, lctrAclHdr_t *pAclHdr, uint8_t *pBuf) @@ -469,8 +464,6 @@ static void lctrAssembleDataPdu(lctrConnCtx_t *pCtx, lctrAclHdr_t *pAclHdr, uint * \param fragLen Fragment length. * \param pAclHdr ACL header. * \param pAclBuf ACL buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrTxDataPduQueue(lctrConnCtx_t *pCtx, uint16_t fragLen, lctrAclHdr_t *pAclHdr, uint8_t *pAclBuf) @@ -480,7 +473,7 @@ void lctrTxDataPduQueue(lctrConnCtx_t *pCtx, uint16_t fragLen, lctrAclHdr_t *pAc lctrTxBufDesc_t *pDesc; - if ((pDesc = lctrAllocTxBufDesc()) == NULL) + if ((pDesc = lctrAllocConnTxBufDesc()) == NULL) { LL_TRACE_ERR1("Failed to allocate transmit buffer descriptor: connHandle=%u", pAclHdr->connHandle); WsfMsgFree(pAclBuf); @@ -609,8 +602,6 @@ void lctrTxDataPduQueue(lctrConnCtx_t *pCtx, uint16_t fragLen, lctrAclHdr_t *pAc * * \param pCtx Connection context. * \param pBuf Data PDU buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrTxCtrlPduQueue(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -834,8 +825,6 @@ bool_t lctrTxQueuePop(lctrConnCtx_t *pCtx) * \brief Pop top element from Tx queue. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrTxQueuePopCleanup(lctrConnCtx_t *pCtx) @@ -849,7 +838,7 @@ void lctrTxQueuePopCleanup(lctrConnCtx_t *pCtx) #ifndef LCTR_CONN_NO_TIFS_REASSEMBLY WsfMsgFree(pDesc->pAclPdu - HCI_ACL_HDR_LEN); #endif - lctrFreeTxBufDesc(pDesc); + lctrFreeConnTxBufDesc(pDesc); lctrDataTxIncAvailBuf(); pCtx->numTxComp++; } @@ -887,7 +876,7 @@ uint8_t lctrTxQueueClear(lctrConnCtx_t *pCtx) #ifndef LCTR_CONN_NO_TIFS_REASSEMBLY WsfMsgFree(pDesc->pAclPdu - HCI_ACL_HDR_LEN); #endif - lctrFreeTxBufDesc(pDesc); + lctrFreeConnTxBufDesc(pDesc); lctrDataTxIncAvailBuf(); numTxBufs++; @@ -932,8 +921,6 @@ uint8_t *lctrRxPduAlloc(uint16_t maxRxLen) * \brief Free a receive data PDU buffer. * * \param pBuf PDU data buffer to free. - * - * \return None. */ /*************************************************************************************************/ void lctrRxPduFree(uint8_t *pBuf) @@ -951,8 +938,6 @@ void lctrRxPduFree(uint8_t *pBuf) * \param pBuf PDU data buffer to queue. * \param eventCounter Event counter. * \param connHandle Connection handle. - * - * \return None. */ /*************************************************************************************************/ void lctrRxEnq(uint8_t *pBuf, uint16_t eventCounter, uint16_t connHandle) @@ -994,10 +979,8 @@ uint8_t *lctrRxDeq(uint16_t *pConnHandle) /*! * \brief Enqueue a receive data PDU buffer for a connection. * - * \param pCtx Connection context; + * \param pCtx Connection context. * \param pBuf PDU data buffer to queue. - * - * \return None. */ /*************************************************************************************************/ void lctrRxConnEnq(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -1010,7 +993,7 @@ void lctrRxConnEnq(lctrConnCtx_t *pCtx, uint8_t *pBuf) /*! * \brief Dequeue a receive data PDU buffer for a connection as a ACL message. * - * \param pCtx Connection context; + * \param pCtx Connection context. * * \return Pointer to the start of the ACL message. * @@ -1051,12 +1034,6 @@ uint8_t *lctrRxConnDeqAcl(lctrConnCtx_t *pCtx) } lctrPackAclHdr(pAclBuf, &aclHdr); - - /* Move ACL data beside the header if necessary. */ - if (LCTR_DATA_PDU_START_OFFSET + LL_DATA_HDR_LEN > HCI_ACL_HDR_LEN) - { - memmove(pAclBuf + HCI_ACL_HDR_LEN, pAclBuf + LCTR_DATA_PDU_START_OFFSET + LL_DATA_HDR_LEN, aclHdr.len); - } } return pAclBuf; @@ -1066,7 +1043,7 @@ uint8_t *lctrRxConnDeqAcl(lctrConnCtx_t *pCtx) /*! * \brief Clear receive queue for a connection. * - * \param pCtx Connection context; + * \param pCtx Connection context. * * \return Number of freed buffers. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_master.c index 1f97b53793b..b099194ac0c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,8 +45,6 @@ * * \param pCtx Connection context. * \param pBuf PDU buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -99,8 +98,6 @@ static void lctrMstProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) /*************************************************************************************************/ /*! * \brief Master Tx data pending task event handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstConnTxPendingHandler(void) @@ -129,8 +126,6 @@ static void lctrMstConnTxPendingHandler(void) /*************************************************************************************************/ /*! * \brief Master connection reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstConnResetHandler(void) @@ -138,6 +133,7 @@ static void lctrMstConnResetHandler(void) BbBleConnSlaveInit(); BbBleConnMasterInit(); SchRmInit(); + SchTmInit(); lctrConnDefaults(); LmgrConnInit(); } @@ -147,8 +143,6 @@ static void lctrMstConnResetHandler(void) * \brief Execute master state machine. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstConnExecute(lctrConnMsg_t *pMsg) @@ -176,34 +170,87 @@ static void lctrMstConnExecute(lctrConnMsg_t *pMsg) * \brief Master connection message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstConnDisp(lctrConnMsg_t *pMsg) { if (pMsg->hdr.dispId != LCTR_DISP_BCST) { - WSF_ASSERT(pMsg->hdr.handle < (pLctrRtCfg->maxConn + (pLctrRtCfg->maxCis * pLctrRtCfg->maxCig))); + pLctrConnMsg = pMsg; + + WSF_ASSERT(pMsg->hdr.handle < (pLctrRtCfg->maxConn + pLctrRtCfg->maxCis)); lctrMstConnExecute(pMsg); } else { for (pMsg->hdr.handle = 0; pMsg->hdr.handle < pLctrRtCfg->maxConn; pMsg->hdr.handle++) { + pLctrConnMsg = pMsg; + lctrMstConnExecute(pMsg); } } } +/*************************************************************************************************/ +/*! + * \brief Host channel class update handler for connections. + * + * \param chanMap Updated channel map. + * + * \return Status code. + */ +/*************************************************************************************************/ +static uint8_t lctrConnChClassUpdate(uint64_t chanMap) +{ + lctrChanMapUpdate_t *pMsg; + uint16_t handle; + uint8_t status = LL_SUCCESS; + + /* Update for connections */ + for (handle = 0; handle < pLctrRtCfg->maxConn; handle++) + { + if ((LctrIsConnHandleEnabled(handle)) && + (LctrGetRole(handle) == LL_ROLE_MASTER)) + { + /* Update the channel map for CIS master as well. */ + if (LctrUpdateCisChanMapFn) + { + LctrUpdateCisChanMapFn(handle); + } + + if (LctrIsProcActPended(handle, LCTR_CONN_MSG_API_CHAN_MAP_UPDATE) == TRUE) + { + status = LL_ERROR_CODE_CMD_DISALLOWED; + } + + if ((pMsg = (lctrChanMapUpdate_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = handle; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_CHAN_MAP_UPDATE; + + pMsg->chanMap = chanMap; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + else + { + LL_TRACE_ERR0("lctrConnChClassUpdate: out of message buffers"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + } + + return status; +} + /*************************************************************************************************/ /*! * \brief Build a connection operation. * * \param pCtx Connection context. * \param pConnInd Connection indication. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnBuildOp(lctrConnCtx_t *pCtx, lctrConnInd_t *pConnInd) @@ -219,8 +266,8 @@ void lctrMstConnBuildOp(lctrConnCtx_t *pCtx, lctrConnInd_t *pConnInd) /*** Connection context setup ***/ - /* pCtx->lastChanIdx = 0; */ /* cleared in lctrMstConnAdjustOpStart() */ - /* pCtx->eventCounter = 0; */ /* cleared in lctrMstConnAdjustOpStart() */ + pCtx->lastChanIdx = 0; + pCtx->eventCounter = 0; pCtx->chanMask = pConnInd->chanMask; pCtx->hopInc = pConnInd->hopInc; pCtx->connInterval = pConnInd->interval; @@ -252,6 +299,7 @@ void lctrMstConnBuildOp(lctrConnCtx_t *pCtx, lctrConnInd_t *pConnInd) /* Set PHY options to default behavior for connection. */ pBle->chan.initTxPhyOptions = BB_PHY_OPTIONS_BLE_S8; /* TODO: Change to scanned PHY options from extended advertiser. */ + lctrInitPhyTxPower(pCtx); #if (LL_ENABLE_TESTER) pBle->chan.accAddrRx = pConnInd->accessAddr ^ llTesterCb.dataAccessAddrRx; @@ -272,8 +320,7 @@ void lctrMstConnBuildOp(lctrConnCtx_t *pCtx, lctrConnInd_t *pConnInd) /*** General setup ***/ - /* pOp->dueOffsetUsec = 0; */ /* cleared in alloc */ - pOp->minDurUsec = pCtx->localConnDurUsec; + pOp->minDurUsec = pCtx->effConnDurUsec; pOp->maxDurUsec = LCTR_CONN_IND_US(pCtx->connInterval); /* pOp->due = scanRefTime + BB_US_TO_BB_TICKS(maxOffsetUsec); */ /* set in lctrMstConnAdjustOpStart() */ @@ -301,8 +348,6 @@ void lctrMstConnBuildOp(lctrConnCtx_t *pCtx, lctrConnInd_t *pConnInd) * \brief Set the establish connection state. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrMstSetEstablishConn(lctrConnCtx_t *pCtx) @@ -325,14 +370,12 @@ void lctrMstSetEstablishConn(lctrConnCtx_t *pCtx) LL_TRACE_INFO1(" >>> Connection established, handle=%u <<<", LCTR_GET_CONN_HANDLE(pCtx)); LL_TRACE_INFO1(" connIntervalUsec=%u", LCTR_CONN_IND_US(pCtx->connInterval)); - LL_TRACE_INFO1(" due=%u", pCtx->connBod.due); + LL_TRACE_INFO1(" dueUsec=%u", pCtx->connBod.dueUsec); } /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for connectable master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstConnInit(void) @@ -358,6 +401,8 @@ void LctrMstConnInit(void) /* Add channel selection handler. */ lctrChSelHdlr[LL_CH_SEL_1] = lctrSelectNextDataChannel; + lctrRegisterChClassHandler(lctrConnChClassUpdate); + lctrConnDefaults(); /* Set supported features. */ @@ -411,70 +456,3 @@ uint8_t lctrComputeHopInc(void) /* Valid value range is 5 to 16. */ return (((randNum >> 0) & 7) + ((randNum >> 8) & 3) + ((randNum >> 16) & 1)) + 5; } - -/*************************************************************************************************/ -/*! - * \brief Adjust the start time of a pre-established connection BOD. - * - * \param pCtx Connection context. - * \param scanRefTime Scan BOD reference time. - * \param scanMinDurUsec Scan BOD minimum duration. - * \param pConnInd Connection indication. - * - * \return First CE due time. - */ -/*************************************************************************************************/ -uint32_t lctrMstConnAdjustOpStart(lctrConnCtx_t *pCtx, uint32_t scanRefTime, uint32_t scanMinDurUsec, lctrConnInd_t *pConnInd) -{ - /* Pre-resolve common structures for efficient access. */ - BbOpDesc_t * const pOp = &pCtx->connBod; - - /*** Connection context setup ***/ - - pCtx->lastChanIdx = 0; - pCtx->eventCounter = 0; - - /*** General setup ***/ - - /* Use maximum txWindowOffset (i.e. connInterval) to maximize scan opportunity. */ - uint32_t maxOffsetUsec = SchRmGetOffsetUsec(LCTR_CONN_IND_US(pConnInd->interval), LCTR_GET_CONN_HANDLE(pCtx), scanRefTime); - - if (maxOffsetUsec <= scanMinDurUsec) - { - /* To avoid the case that the connection BOD might kill the scan BOD which does the scan for the connection. */ - maxOffsetUsec += LCTR_CONN_IND_US(pConnInd->interval); - } - - pOp->due = scanRefTime + BB_US_TO_BB_TICKS(maxOffsetUsec); - - /*** Commit operation ***/ - - WSF_ASSERT(pCtx->connInterval); - - uint32_t firstCeDue = pOp->due; - uint32_t anchorPoint = pOp->due; - uint16_t numIntervals = 0; - - while (TRUE) - { - if (SchInsertAtDueTime(pOp, lctrConnResolveConflict)) - { - break; - } - - LL_TRACE_WARN1("!!! Establish CE schedule conflict handle=%u", LCTR_GET_CONN_HANDLE(pCtx)); - - numIntervals += 1; - pCtx->eventCounter += 1; - - uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval); - uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec); - int16_t dueOffsetUsec = connInterUsec - BB_TICKS_TO_US(connInter); - - /* Advance to next interval. */ - pOp->due = anchorPoint + connInter; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); - } - - return firstCeDue; -} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_slave.c index 10dda5c75ce..79830502ee5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave connection operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave connection operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -39,16 +40,18 @@ /************************************************************************************************** Global Variables **************************************************************************************************/ + +/*! \brief SCA PPM table. */ const uint16_t scaPpmTbl[] = { - 500, /* LL_MCA_500_PPM */ - 250, /* LL_MCA_250_PPM */ - 150, /* LL_MCA_150_PPM */ - 100, /* LL_MCA_100_PPM */ - 75, /* LL_MCA_75_PPM */ - 50, /* LL_MCA_50_PPM */ - 30, /* LL_MCA_30_PPM */ - 20 /* LL_MCA_20_PPM */ + 500, /*!< LL_MCA_500_PPM */ + 250, /*!< LL_MCA_250_PPM */ + 150, /*!< LL_MCA_150_PPM */ + 100, /*!< LL_MCA_100_PPM */ + 75, /*!< LL_MCA_75_PPM */ + 50, /*!< LL_MCA_50_PPM */ + 30, /*!< LL_MCA_30_PPM */ + 20 /*!< LL_MCA_20_PPM */ }; /*************************************************************************************************/ @@ -56,8 +59,6 @@ const uint16_t scaPpmTbl[] = * \brief Process a received connection indication PDU in slave role. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvProcessConnInd(lctrConnMsg_t *pMsg) @@ -92,8 +93,6 @@ static void lctrSlvProcessConnInd(lctrConnMsg_t *pMsg) * * \param pCtx Connection context. * \param pBuf PDU buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -128,14 +127,13 @@ static void lctrSlvProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) /*************************************************************************************************/ /*! * \brief Slave connection reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvConnResetHandler(void) { BbBleConnSlaveInit(); SchRmInit(); + SchTmInit(); lctrConnDefaults(); LmgrConnInit(); } @@ -145,8 +143,6 @@ static void lctrSlvConnResetHandler(void) * \brief Execute slave state machine. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvConnExecute(lctrConnMsg_t *pMsg) @@ -167,26 +163,50 @@ static void lctrSlvConnExecute(lctrConnMsg_t *pMsg) * \brief Slave connection message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvConnDisp(lctrConnMsg_t *pMsg) { if (pMsg->hdr.dispId != LCTR_DISP_BCST) { + pLctrConnMsg = pMsg; + WSF_ASSERT(pMsg->hdr.handle < pLctrRtCfg->maxConn); lctrSlvConnExecute(pMsg); -} + } else { for (pMsg->hdr.handle = 0; pMsg->hdr.handle < pLctrRtCfg->maxConn; pMsg->hdr.handle++) { + pLctrConnMsg = pMsg; + lctrSlvConnExecute(pMsg); } } } +/*************************************************************************************************/ +/*! + * \brief Get reference time(due time) of the slave connection handle. + * + * \param connHandle Connection handle. + * + * \return Due time in microseconds of the connection handle. + */ +/*************************************************************************************************/ +static uint32_t lctrGetSlvConnRefTime(uint8_t connHandle) +{ + uint32_t refTime = 0; + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(connHandle); + + if (pCtx->enabled && (pCtx->bleData.chan.opType == BB_BLE_OP_SLV_CONN_EVENT)) + { + refTime = pCtx->connBod.dueUsec; + } + + return refTime; +} + /*************************************************************************************************/ /*! * \brief Compute the total clock accuracy. @@ -215,8 +235,6 @@ uint16_t lctrCalcTotalAccuracy(uint8_t mstScaIdx) * * \param pCtx Connection context. * - * \return None. - * * This routine is called in response to a received CONNECTION_REQ PDU. The PDU must already * be decoded in the lctrPduSlvAdvb variable prior to this call. */ @@ -294,6 +312,7 @@ void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx) pBle->chan.accAddr = pConnInd->accessAddr; pBle->chan.crcInit = pConnInd->crcInit; pBle->chan.txPhy = pBle->chan.rxPhy = pLctrConnMsg->connEstablish.phy; + lctrInitPhyTxPower(pCtx); #if (LL_ENABLE_TESTER) pBle->chan.accAddrRx = pConnInd->accessAddr ^ llTesterCb.dataAccessAddrRx; @@ -315,18 +334,14 @@ void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx) /*** General setup ***/ const uint32_t txWinOffsetUsec = LCTR_CONN_IND_US(txWinOffsetCnt); - const uint32_t txWinOffset = BB_US_TO_BB_TICKS(txWinOffsetUsec); const uint32_t txWinSizeUsec = LCTR_CONN_IND_US(pConnInd->txWinSize); const uint32_t wwOffsetUsec = lctrCalcWindowWideningUsec((txWinOffsetUsec + txWinSizeUsec), pCtx->data.slv.totalAcc); - const uint32_t wwOffset = BB_US_TO_BB_TICKS(wwOffsetUsec); - int16_t dueOffsetUsec = (txWinOffsetUsec - wwOffsetUsec) - BB_TICKS_TO_US(txWinOffset - wwOffset); - pCtx->data.slv.anchorPoint = pLctrConnMsg->connEstablish.connIndEndTs + txWinOffset; /* estimated initial anchor point */ + pCtx->data.slv.anchorPointUsec = pLctrConnMsg->connEstablish.connIndEndTsUsec + txWinOffsetUsec; /* estimated initial anchor point */ pCtx->data.slv.txWinSizeUsec = txWinSizeUsec; - pOp->due = pCtx->data.slv.anchorPoint - wwOffset; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); - pOp->minDurUsec = txWinSizeUsec + pCtx->localConnDurUsec + (wwOffsetUsec << 1); + pOp->dueUsec = pCtx->data.slv.anchorPointUsec - wwOffsetUsec; + pOp->minDurUsec = txWinSizeUsec + pCtx->effConnDurUsec + (wwOffsetUsec << 1); /* pOp->maxDurUsec = 0; */ /* cleared in alloc */ pOp->reschPolicy = BB_RESCH_FIXED; @@ -339,7 +354,7 @@ void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx) /*** BLE connection setup ***/ pConn->rxSyncDelayUsec = txWinSizeUsec + (wwOffsetUsec << 1) + - BB_TICKS_TO_US(1); /* rounding compensation when computing reqEndTs */ + 1; /* rounding compensation when computing reqEndTs */ pConn->execCback = lctrSlvConnBeginOp; pConn->cancelCback = lctrSlvConnCleanupOp; pConn->txDataCback = lctrSlvConnTxCompletion; @@ -358,9 +373,8 @@ void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx) { LL_TRACE_INFO1(" >>> Connection established, handle=%u <<<", LCTR_GET_CONN_HANDLE(pCtx)); LL_TRACE_INFO1(" connIntervalUsec=%u", LCTR_CONN_IND_US(pCtx->connInterval)); - LL_TRACE_INFO1(" due=%u", pOp->due); - LL_TRACE_INFO1(" offsetUsec=%u", pOp->dueOffsetUsec); - + LL_TRACE_INFO1(" dueUsec=%u", pOp->dueUsec); + LL_TRACE_INFO1(" minDurUsec=%u", pOp->minDurUsec); break; } @@ -370,24 +384,22 @@ void lctrSlvConnBuildOp(lctrConnCtx_t *pCtx) /* Initial eventCounter starts at 0; equivalent to unsynchronized intervals. */ uint32_t unsyncTimeUsec = LCTR_CONN_IND_US(pCtx->connInterval * pCtx->eventCounter); - uint32_t unsyncTime = BB_US_TO_BB_TICKS(unsyncTimeUsec); uint32_t wwTotalUsec = lctrCalcWindowWideningUsec(unsyncTimeUsec, pCtx->data.slv.totalAcc); - uint32_t wwTotal = BB_US_TO_BB_TICKS(wwTotalUsec); - dueOffsetUsec = (unsyncTimeUsec - wwTotalUsec) - BB_TICKS_TO_US(unsyncTime - wwTotal); /* Advance to next interval. */ - pOp->due = pCtx->data.slv.anchorPoint + unsyncTime - wwTotal; - pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); + pOp->dueUsec = pCtx->data.slv.anchorPointUsec + unsyncTimeUsec - wwTotalUsec; + pOp->minDurUsec = ceDurUsec + wwTotalUsec; pConn->rxSyncDelayUsec = ceSyncDlyUsec + (wwTotalUsec << 1); } + + /* Update topology manager information. */ + SchTmAdd(LCTR_GET_CONN_HANDLE(pCtx), LCTR_CONN_IND_US(pCtx->connInterval), pCtx->effConnDurUsec, TRUE, lctrGetSlvConnRefTime); } /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for connectable slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvConnInit(void) @@ -450,8 +462,6 @@ void LctrSlvConnInit(void) /*************************************************************************************************/ /*! * \brief Set default values for connection. - * - * \return None. */ /*************************************************************************************************/ void lctrConnDefaults(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_master.c index d58c4ab9a22..db7d60f372b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master encryption implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master encryption implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ * * \param pCtx Connection context. * \param pBuf PDU buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstEncProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -92,8 +91,6 @@ static void lctrMstEncProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for connectable encrypted master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstConnEncInit(void) @@ -108,7 +105,7 @@ void LctrMstConnEncInit(void) lctrCtrlPduHdlr = lctrMstEncProcessDataPdu; /* Add packet encryption handlers. */ - lctrInitCipherBlkHdlr = PalCryptoAesSetupCipherBlock; + lctrInitCipherBlkHdlr = PalCryptoAesEnable; #if (!BB_ENABLE_INLINE_ENC_TX) lctrPktEncryptHdlr = PalCryptoAesCcmEncrypt; #else diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_slave.c index a296d96fc3a..1a506a943ca 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave encryption implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave encryption implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,8 +35,6 @@ * * \param pCtx Connection context. * \param pBuf PDU buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrSlvEncProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) @@ -70,8 +69,6 @@ static void lctrSlvEncProcessDataPdu(lctrConnCtx_t *pCtx, uint8_t *pBuf) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for connectable encrypted slave. - * - * \return None. */ /*************************************************************************************************/ void LctrSlvConnEncInit(void) @@ -87,7 +84,7 @@ void LctrSlvConnEncInit(void) } /* Add packet encryption handlers. */ - lctrInitCipherBlkHdlr = PalCryptoAesSetupCipherBlock; + lctrInitCipherBlkHdlr = PalCryptoAesEnable; #if (!BB_ENABLE_INLINE_ENC_TX) lctrPktEncryptHdlr = PalCryptoAesCcmEncrypt; #else @@ -132,7 +129,7 @@ uint32_t LctrGetAuthPayloadTimeout(uint16_t handle) * \param handle Connection handle. * \param timeoutMs New timeout value in milliseconds. * - * \return None. + * \return TRUE if successful, FALSE if not. */ /*************************************************************************************************/ bool_t LctrSetAuthPayloadTimeout(uint16_t handle, uint32_t timeoutMs) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master.c index b03fe50bc86..a03d60bec09 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master scanning operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master scanning operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -43,8 +44,6 @@ lctrMstScanCtx_t lctrMstInit; /*************************************************************************************************/ /*! * \brief Master initiate reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstInitResetHandler(void) @@ -57,8 +56,6 @@ static void lctrMstInitResetHandler(void) * \brief Master initiate message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstInitDisp(lctrMsgHdr_t *pMsg) @@ -66,26 +63,6 @@ static void lctrMstInitDisp(lctrMsgHdr_t *pMsg) lctrMstInitExecuteSm(pMsg->event); } -/*************************************************************************************************/ -/*! - * \brief Handler for pre-initiate scan execution. - * - * \param pOp BB operation descriptor. - * - * \return None. - */ -/*************************************************************************************************/ -static void lctrMstPreInitiateExecHandler(BbOpDesc_t *pOp) -{ - /* Setup connection's initial CE now that RM is synchronized BB. This step must be performed - * before initiate's scan operation sets up its executing duration (i.e. "pre-execute"). */ - lctrMstInit.data.init.firstCeDue = lctrMstConnAdjustOpStart(LCTR_GET_CONN_CTX(lctrMstInit.data.init.connHandle), - pOp->due, - pOp->minDurUsec, - &lctrMstInit.data.init.connInd); - lctrMstInit.data.init.connBodLoaded = TRUE; -} - /*************************************************************************************************/ /*! * \brief Build initiate connection operation. @@ -93,8 +70,6 @@ static void lctrMstPreInitiateExecHandler(BbOpDesc_t *pOp) * \param pConnSpec Connection spec. * \param peerAddrType Peer address type. * \param peerAddr Peer address. - * - * \return None. */ /*************************************************************************************************/ void lctrMstInitiateBuildOp(LlConnSpec_t *pConnSpec, uint8_t peerAddrType, uint64_t peerAddr) @@ -146,14 +121,13 @@ void lctrMstInitiateBuildOp(LlConnSpec_t *pConnSpec, uint8_t peerAddrType, uint6 pScan->scanChMap = lmgrMstScanCb.scanChanMap; - pScan->preExecCback = lctrMstPreInitiateExecHandler; pScan->rxAdvCback = lctrMstInitiateAdvPktHandler; if ((pScan->pRxAdvBuf = WsfMsgAlloc(LCTR_ADVB_BUF_SIZE)) == NULL) { /* Attempt to obtain buffer on next advertising operation. */ LL_TRACE_ERR0("Could not allocate advertising buffer"); - // TODO need OOM recovery + /* TODO need OOM recovery */ WSF_ASSERT(FALSE); } @@ -251,8 +225,6 @@ void lctrMstInitiateBuildOp(LlConnSpec_t *pConnSpec, uint8_t peerAddrType, uint6 /*************************************************************************************************/ /*! * \brief Commit initiate connection operation. - * - * \return None. */ /*************************************************************************************************/ void lctrMstInitiateOpCommit(void) @@ -269,14 +241,12 @@ void lctrMstInitiateOpCommit(void) lctrMstInit.shutdown = FALSE; SchInsertNextAvailable(pOp); - lctrMstInit.scanWinStart = pOp->due; + lctrMstInit.scanWinStartUsec = pOp->dueUsec; } /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for initiating master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstInitInit(void) @@ -293,8 +263,6 @@ void LctrMstInitInit(void) /*************************************************************************************************/ /*! * \brief Set default values for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstInitDefaults(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master_ae.c index a3c48c35e23..6921013794b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_init_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master scanning operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master scanning operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,6 +35,21 @@ #include #include +/************************************************************************************************** + Macros +**************************************************************************************************/ +/*! \brief Resolve the extended initiate handle from the context pointer. */ +#define LCTR_GET_EXT_INIT_HANDLE(pCtx) (pCtx - lctrMstExtInitTbl) + +/*! \brief Typical PDU length of ADV_EXT_IND when initiating connection. */ +#define LCTR_INIT_ADV_EXT_IND_LEN 7 /*!< Includes Flags + ADI + AuxPtr. */ + +/*! \brief Typical PDU length of AUX_ADV_IND when initiating connection. */ +#define LCTR_INIT_AUX_ADV_IND_LEN 10 /*!< Includes Flags + AdvA + ADI. */ + +/*! \brief Typical PDU length of ADV_IND when initiating connection with legacy packets. */ +#define LCTR_INIT_ADV_IND_LEN 6 + /************************************************************************************************** Globals **************************************************************************************************/ @@ -47,8 +63,6 @@ lctrExtInitCtrlBlk_t lctrMstExtInit; /*************************************************************************************************/ /*! * \brief Master initiate reset handler. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtInitResetHandler(void) @@ -61,8 +75,6 @@ static void lctrMstExtInitResetHandler(void) * \brief Execute common master initiate state machine. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtInitExecuteCommonSm(LctrExtScanMsg_t *pMsg) @@ -94,7 +106,7 @@ static void lctrMstExtInitExecuteCommonSm(LctrExtScanMsg_t *pMsg) if ((status = lctrExtInitSetupInitiate(&lctrMstExtInitTbl[i], pExtInitMsg->peerAddrType, pExtInitMsg->peerAddr, pExtInitMsg->filterPolicy, pExtInitMsg->ownAddrType)) != LL_SUCCESS) { - // TODO for multiple scanners, cleanup upon failure + /* TODO for multiple scanners, cleanup upon failure */ break; } } @@ -145,8 +157,6 @@ static void lctrMstExtInitExecuteCommonSm(LctrExtScanMsg_t *pMsg) * \brief Master initiate message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrMstExtInitDisp(LctrExtScanMsg_t *pMsg) @@ -270,7 +280,6 @@ uint8_t lctrMstExtInitiateBuildOp(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t *p pScan->scanChMap = lmgrMstScanCb.scanChanMap; - pScan->preExecCback = lctrMstExtPreInitiateExecHandler; pScan->rxAdvCback = lctrMstInitiateRxExtAdvPktHandler; pScan->rxAdvPostCback = lctrMstInitiateRxExtAdvPktPostProcessHandler; @@ -284,7 +293,7 @@ uint8_t lctrMstExtInitiateBuildOp(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t *p pScan->txReqCback = lctrMstExtConnIndTxCompHandler; - // TODO move to common/shared init + /* TODO move to common/shared init */ lctrConnInd_t * const pConnInd = &pExtInitCtx->data.init.connInd; pConnInd->accessAddr = lctrComputeAccessAddr(); @@ -371,8 +380,6 @@ uint8_t lctrMstExtInitiateBuildOp(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t *p * \brief Commit initiate connection operation. * * \param pExtInitCtx Extended scan context of the initiator. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtInitiateOpCommit(lctrExtScanCtx_t *pExtInitCtx) @@ -390,7 +397,7 @@ void lctrMstExtInitiateOpCommit(lctrExtScanCtx_t *pExtInitCtx) pExtInitCtx->shutdown = FALSE; SchInsertNextAvailable(pOp); - pExtInitCtx->data.init.scanWinStart = pOp->due; + pExtInitCtx->data.init.scanWinStartUsec = pOp->dueUsec; } /*************************************************************************************************/ @@ -524,8 +531,6 @@ uint8_t lctrMstAuxInitiateBuildOp(lctrExtScanCtx_t *pExtInitCtx, LlConnSpec_t *p /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for initiating master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtInitInit(void) @@ -548,8 +553,6 @@ void LctrMstExtInitInit(void) /*************************************************************************************************/ /*! * \brief Set default values for scanning master. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtInitDefaults(void) @@ -566,8 +569,6 @@ void LctrMstExtInitDefaults(void) * \brief Set enabled initiate scanning PHY. * * \param scanPhy Enabled scanning PHY. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtInitSetScanPhy(uint8_t scanPhy) @@ -582,8 +583,6 @@ void LctrMstExtInitSetScanPhy(uint8_t scanPhy) * \brief Clear (disable) scanning PHY. * * \param scanPhy Disabled scanning PHY. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtInitClearScanPhy(uint8_t scanPhy) @@ -600,8 +599,6 @@ void LctrMstExtInitClearScanPhy(uint8_t scanPhy) * \param initPhy Extended initiating PHY. * \param pScanParam Extended initiating scan parameters. * \param pConnSpec Connection specification. - * - * \return None. */ /*************************************************************************************************/ void LctrMstExtInitParam(uint8_t initPhy, const LlExtInitScanParam_t *pScanParam, const LlConnSpec_t *pConnSpec) @@ -621,8 +618,6 @@ void LctrMstExtInitParam(uint8_t initPhy, const LlExtInitScanParam_t *pScanParam * * \param pExtInitCtx Extended initiate context. * \param event Extended scan event. - * - * \return None. */ /*************************************************************************************************/ void lctrSendExtInitMsg(lctrExtScanCtx_t *pExtInitCtx, uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso.c new file mode 100644 index 00000000000..369609871c6 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso.c @@ -0,0 +1,1196 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller connected isochronous stream main implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis.h" +#include "lctr_int_bis.h" +#include "lctr_int_iso.h" +#include "hci_defs.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include "pal_codec.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Codec event handlers (function pointers to decouple linker dependencies). */ +lctrCodecHandlers_t lctrCodecHdlr; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Process received ISO test data. + * + * \param pCisCtx CIS context. + * \param pDataBuf Data buffer. + * \param dataLen Data length. + */ +/*************************************************************************************************/ +static void lctrIsoProcessRxTestData(lctrCisCtx_t *pCisCtx, uint8_t *pDataBuf, uint8_t dataLen) +{ + uint16_t pldType = 0; + uint64_t plTestCounter = pCisCtx->rxPktCounter; + + if (pCisCtx->rxPendInit) + { + memcpy(&pCisCtx->expectedPkt, pDataBuf, 4); + pCisCtx->rxPendInit = FALSE; + LL_TRACE_INFO1("lctrCisRxPostProcessing, Rx counter initialized to %d", pCisCtx->expectedPkt); + } + + switch (pCisCtx->isoRxPldType) + { + case LL_ISO_PLD_TYPE_MAX_LEN: + + pldType = (pCisCtx->role == LL_ROLE_MASTER) ? pCisCtx->sduSizeSToM : pCisCtx->sduSizeMToS; + break; + + case LL_ISO_PLD_TYPE_VAR_LEN: + pldType = plTestCounter * 4; + pldType = WSF_MIN(pCisCtx->localDataPdu.maxRxLen, pldType); + break; + + case LL_ISO_PLD_TYPE_ZERO_LEN: + default: + break; + } + + uint32_t pktNum = 0; + if (dataLen >= LL_ISO_TEST_VAR_MIN_LEN) + { + memcpy(&pktNum, pDataBuf, 4); + } + + switch (pCisCtx->isoRxPldType) + { + case LL_ISO_PLD_TYPE_MAX_LEN: + if ((dataLen == pldType) && + (pktNum == pCisCtx->expectedPkt)) + { + pCisCtx->numRxSuccess++; + } + else + { + pCisCtx->expectedPkt = pktNum + 1; + pCisCtx->numRxFailed++; + } + break; + + case LL_ISO_PLD_TYPE_VAR_LEN: + if ((dataLen >= LL_ISO_TEST_VAR_MIN_LEN) && + (pktNum == pCisCtx->expectedPkt)) + { + pCisCtx->numRxSuccess++; + } + else + { + pCisCtx->expectedPkt = pktNum + 1; + pCisCtx->numRxFailed++; + } + break; + + case LL_ISO_PLD_TYPE_ZERO_LEN: + if (dataLen == 0) + { + pCisCtx->numRxSuccess++; + } + else + { + pCisCtx->numRxFailed++; + } + break; + + default: + LL_TRACE_ERR1("Invalid value pldType=%u", pldType); + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Tx test. + * + * \param pCisCtx CIS context. + * \param pldType Payload length type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +static uint8_t lctrCisTxTest(lctrCisCtx_t *pCisCtx, uint8_t pldType) +{ + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + + if (((pCisCtx->bnMToS == 0) && (pCisCtx->role == LL_ROLE_MASTER)) || + ((pCisCtx->bnSToM == 0) && (pCisCtx->role == LL_ROLE_SLAVE))) + { + LL_TRACE_WARN0("Transmit burst number must be greater than 0"); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + if (pldType > LL_ISO_PLD_TYPE_MAX_LEN) + { + LL_TRACE_WARN1("Unknown payload type=%u", pldType); + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + pCisCtx->testTxPktCtr = 0; +#if (LL_ENABLE_TESTER) + pCisCtx->testTxPktCtr = llTesterCb.isoTxTestNumInit; +#endif + pCisCtx->testSduTs = pCigCtx->cigBod.dueUsec; + pCisCtx->testPldType = pldType; + pCisCtx->txTestEnabled = TRUE; + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief CIS read ISO test counters. + * + * \param pCisCtx CIS context. + * \param pStats Pointer to the statistics block. + * + * \return Status error code. + */ +/*************************************************************************************************/ +static uint8_t LctrCisReadTestCounters(lctrCisCtx_t *pCisCtx, LlIsoTestCtrs_t *pStats) +{ + + if (!pCisCtx->rxTestEnabled && + !pCisCtx->txTestEnabled) + { + LL_TRACE_WARN0("Invalid ISO Test state, test mode must be enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (pCisCtx->rxTestEnabled) + { + pStats->numSuccess = pCisCtx->numRxSuccess; + pStats->numMissed = pCisCtx->numRxMissed; + pStats->numFailed = pCisCtx->numRxFailed; + } + else /* if (pCisCtx->txTestEnabled) */ + { + pStats->numSuccess = 0; + pStats->numMissed = 0; + pStats->numFailed = 0; + } + + return LL_SUCCESS; +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Initialize codec resources. + * + * Map codec handlers for codec operations. Function pointer abstraction is used to decouple + * linker dependencies when a codec is not required by the system. + */ +/*************************************************************************************************/ +void LctrInitCodec(void) +{ + /* Add codec. */ + lctrCodecHdlr.start = PalCodecDataStartStream; + lctrCodecHdlr.stop = PalCodecDataStopStream; + lctrCodecHdlr.in = PalCodecDataStreamIn; + lctrCodecHdlr.out = PalCodecDataStreamOut; +} + +/*************************************************************************************************/ +/*! + * \brief Tx data completed task event handler. + */ +/*************************************************************************************************/ +void lctrIsoTxCompletedHandler(void) +{ + WSF_CS_INIT(cs); + + uint8_t numHandles = 0; + uint16_t handle[LL_MAX_CIS] = { 0 }; + uint16_t numSdu[LL_MAX_CIS] = { 0 }; + + /* Cache buffer count within single CS. */ + WSF_CS_ENTER(cs); + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if (pCisCtx->enabled && !pCisCtx->txTestEnabled) + { + if (pCisCtx->numTxComp && (pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED)) + { + numSdu[numHandles] = pCisCtx->numTxComp; + handle[numHandles] = pCisCtx->cisHandle; + pCisCtx->numTxComp = 0; + numHandles++; + } + else if ((pCisCtx->framing == LL_ISO_PDU_TYPE_FRAMED) && pCisCtx->isoalTxCtx.compSdu) + { + numSdu[numHandles] = pCisCtx->isoalTxCtx.compSdu; + handle[numHandles] = pCisCtx->cisHandle; + pCisCtx->numTxComp = 0; /* numTxComp is still recorded in framed, so clear it here. */ + pCisCtx->isoalTxCtx.compSdu = 0; + numHandles++; + } + } + } + + WSF_CS_EXIT(cs); + + if (numHandles) + { + /* Notify host. */ + lmgrPersistCb.sendIsoCompCback(numHandles, handle, numSdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief Rx data pending task event handler. + */ +/*************************************************************************************************/ +void lctrCisRxPendingHandler(void) +{ + uint16_t cisHandle = 0; + uint8_t *pRxBuf; + + /* Route and demux received Data PDUs. */ + + while ((pRxBuf = lctrCisRxDeq(&cisHandle)) != NULL) + { + WSF_ASSERT(pRxBuf); + + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(cisHandle); + lctrIsoalRxCtx_t *pRxCtx = &pCisCtx->isoalRxCtx; + + if (!pCisCtx->enabled) + { + LL_TRACE_ERR1("!!! Data received on terminated cisHandle=%u", cisHandle); + lctrCisRxPduFree(pRxBuf); + continue; + } + + /* Disassemble PDU. */ + lctrCisDataPduHdr_t rxHdr; + lctrCisUnpackDataPduHdr(&rxHdr, pRxBuf); + + /* Decrypt PDU. */ + if (lctrPktDecryptHdlr) + { + if (lctrPktDecryptHdlr(&pCisCtx->bleData.chan.enc, pRxBuf) == FALSE) + { + LL_TRACE_ERR1("!!! MIC verification failed on connHandle=%u", cisHandle); + LL_TRACE_ERR1("!!! MIC verification failed on cisEvtCounter=%u", pCisCtx->cisEvtCounter); + lctrCisRxPduFree(pRxBuf); + lctrSendCisMsg(pCisCtx, LCTR_CIS_MSG_CIS_TERM_MIC_FAILED); + continue; + } + } + + /* Increase packet counter after decryption. */ + lctrCisIncPacketCounterRx(pCisCtx); + + lctrCisDataPduHdr_t cisDataHdr; + lctrCisUnpackDataPduHdr(&cisDataHdr, pRxBuf); + + /* Demux PDU. */ + if (pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + lctrIsoHdr_t isoHdr = { 0 }; + switch (rxHdr.llid) + { + /* Received a end/complete PDU. */ + case LL_LLID_ISO_UNF_END_PDU: + switch (pRxCtx->rxState) + { + case LL_ISO_SDU_STATE_NEW: + isoHdr.pb = LCTR_PB_COMP; + break; + case LL_ISO_SDU_STATE_CONT: + isoHdr.pb = LCTR_PB_LAST; + pRxCtx->rxState = LL_ISO_SDU_STATE_NEW; + break; + default: + lctrCisRxPduFree(pRxBuf); + LL_TRACE_ERR2("!!! Invalid rxState; dropping Rx data PDU, connHandle=%u, rxState=%u", cisHandle, pRxCtx->rxState); + pRxCtx->rxState = LL_ISO_SDU_STATE_NEW; + } + break; + + /* Received a continuation/start PDU. */ + case LL_LLID_ISO_UNF_CONT_PDU: + isoHdr.pb = (pRxCtx->rxState == LL_ISO_SDU_STATE_NEW) ? LCTR_PB_FIRST : LCTR_PB_CONT; + pRxCtx->rxState = LL_ISO_SDU_STATE_CONT; + break; + + /* Unknown LLID. */ + default: + lctrCisRxPduFree(pRxBuf); + LL_TRACE_ERR2("!!! Invalid LLID; dropping Rx data PDU, connHandle=%u llid=%u", cisHandle, rxHdr.llid); + break; + } + + /* If the packet was flushed, change the packet status flag to warn host of errors. */ + if (pRxCtx->pduFlushed) + { + switch (pRxCtx->rxState) + { + case LL_ISO_SDU_STATE_CONT: + /* Lost data since last transfer; invalidate packet. */ + pRxCtx->data.unframed.ps = LCTR_PS_INVALID; + break; + case LL_ISO_SDU_STATE_NEW: + /* This may be a fragmented packet with the end fragment, but no way to tell, so process as normal. */ + pRxCtx->data.unframed.ps = (rxHdr.llid == LL_LLID_ISO_UNF_END_PDU) ? LCTR_PS_INVALID : LCTR_PS_LOST; + break; + } + pRxCtx->pduFlushed = FALSE; + } + + /* Pack isoHdr and queue PDU. */ + if (pRxBuf) + { + uint8_t * pSduBuf = pRxBuf - LCTR_CIS_DATA_PDU_START_OFFSET - HCI_ISO_DL_MAX_LEN; + + /* Pack current packet. */ + isoHdr.handle = cisHandle; + isoHdr.tsFlag = ((isoHdr.pb == LCTR_PB_COMP) || (isoHdr.pb == LCTR_PB_FIRST)) ? 1 : 0; + if (isoHdr.tsFlag) + { + isoHdr.ts = 0xFF; + } + isoHdr.len = pRxBuf[LCTR_ISO_DATA_PDU_LEN_OFFSET]; + /* isoHdr.pktSn = 0; */ + + /* LCTR_PB_COMP and LCTR_PB_FIRST will have their headers re-packed in lctrIsoUnframedRxSduPendQueue. */ + uint8_t headerOffset = lctrIsoPackHdr(pSduBuf, &isoHdr); + + /* Process received buffer for Rx testing purpose. */ + if (pCisCtx->rxTestEnabled == TRUE) + { + lctrIsoProcessRxTestData(pCisCtx, pRxBuf + LL_DATA_HDR_LEN, rxHdr.len); + } + + /* TODO optimize memory layout */ + /* Move payload next to header. */ + if (LCTR_CIS_DATA_PDU_START_OFFSET + LL_ISO_DATA_HDR_LEN > HCI_ISO_HDR_LEN) + { + memmove(pSduBuf + headerOffset , pRxBuf + LL_DATA_HDR_LEN, rxHdr.len); + } + + /* Put onto pending queue until whole SDU is ready to be sent. */ + if (!lctrIsoUnframedRxSduPendQueue(pRxCtx, pSduBuf, cisHandle, rxHdr.len, rxHdr.llid)) + { + break; + } + + /* If it is time to enqueue the SDU, do so here. */ + uint8_t handlerId; + while ((pSduBuf = WsfMsgDeq(&pRxCtx->data.unframed.pendSduQ, &handlerId)) != NULL) + { + /* Enqueue SDU for processing. */ + if (!lctrIsoRxConnEnq(&pCisCtx->dataPathOutCtx, pCisCtx->cisHandle, pSduBuf)) + { + /* The buffer was not freed, so free it now. */ + WsfMsgFree(pSduBuf); + } + } + } + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + switch (rxHdr.llid) + { + case LL_LLID_ISO_FRA_PDU: + { + pCisCtx->dataPathOutCtx.cfg.hci.numRxPend += lctrAssembleRxFramedSdu(pRxCtx, &pCisCtx->dataPathOutCtx.cfg.hci.rxDataQ, pCisCtx->cisHandle, pRxBuf, cisDataHdr.len); + + /* Consume and process packets for iso test mode */ + if (pCisCtx->rxTestEnabled == TRUE) + { + while (pCisCtx->dataPathOutCtx.cfg.hci.numRxPend) + { + lctrIsoHdr_t isoHdr; + uint8_t *pTestRxBuf = lctrIsoRxConnDeq(&pCisCtx->dataPathOutCtx); + lctrIsoUnpackHdr(&isoHdr, pTestRxBuf); + lctrIsoProcessRxTestData(pCisCtx, pTestRxBuf+ HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN, isoHdr.sduLen); + WsfMsgFree(pTestRxBuf); + LctrRxIsoComplete(1); + pCisCtx->dataPathOutCtx.cfg.hci.numRxPend--; + } + } + lctrCisRxPduFree(pRxBuf); + break; + } + + default: + lctrCisRxPduFree(pRxBuf); + LL_TRACE_ERR2("!!! Invalid LLID; dropping Rx data PDU, connHandle=%u llid=%u", cisHandle, rxHdr.llid); + break; + } + } + } + + /* Notify host of pending Rx data. */ + WSF_CS_INIT(cs); + uint8_t numHandles = 0; + uint16_t numSdu[LL_MAX_CIS] = { 0 }; + uint16_t handle[LL_MAX_CIS] = { 0 }; + + /* Cache buffer count within single CS. */ + WSF_CS_ENTER(cs); + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if (pCisCtx->enabled && + pCisCtx->dataPathOutCtx.cfg.hci.numRxPend) + { + if (pCisCtx->dataPathOutCtx.id == LL_ISO_DATA_PATH_HCI) + { + handle[numHandles] = pCisCtx->cisHandle; + numSdu[numHandles] = pCisCtx->dataPathOutCtx.cfg.hci.numRxPend; + pCisCtx->dataPathOutCtx.cfg.hci.numRxPend = 0; + numHandles++; + } + } + } + WSF_CS_EXIT(cs); + + if (numHandles) + { + /* Notify host. */ + lmgrPersistCb.recvIsoPendCback(numHandles, handle, numSdu); + } +} + +/*************************************************************************************************/ +/*! + * \brief Initialize ISO memory resources. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + */ +/*************************************************************************************************/ +uint16_t LctrInitIsoMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + uint8_t *pAvailMem = pFreeMem; + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + /*** Tx Memory ***/ + + freeMemSize -= pAvailMem - pFreeMem; + uint16_t memUsed = lctrIsoTxInitMem(pAvailMem, freeMemSize); + if (memUsed == 0) + { + LL_TRACE_ERR2("LctrInitIsoMem: failed to allocate descriptors, need=%u available=%u", (pAvailMem - pFreeMem), freeMemSize); + WSF_ASSERT(FALSE); + return 0; + } + + pAvailMem += memUsed; + + return (pAvailMem - pFreeMem); +} + +/*************************************************************************************************/ +/*! + * \brief Transmit ISO data path. + * + * \param pIsoBuf ISO buffer. + */ +/*************************************************************************************************/ +void LctrTxIso(uint8_t *pIsoBuf) +{ + lctrIsoHdr_t isoHdr; + + /*** Disassemble ISO packet. ***/ + + lctrIsoUnpackHdr(&isoHdr, pIsoBuf); + + if (isoHdr.sduLen > pLctrRtCfg->maxIsoSduLen) + { + LL_TRACE_ERR2("Invalid ISO header: invalid packet length, actLen=%u, maxLen=%u", isoHdr.sduLen, pLctrRtCfg->maxIsoSduLen); + WsfMsgFree(pIsoBuf); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + return; + } + + if (lmgrIsoCb.availTxBuf == 0) + { + LL_TRACE_ERR1("ISO Tx path flow controlled, handle=%u", isoHdr.handle); + WsfMsgFree(pIsoBuf); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + return; + } + + uint16_t expIsoLen = isoHdr.len - HCI_ISO_DL_MIN_LEN + ((isoHdr.tsFlag) ? HCI_ISO_TS_LEN : 0); + if (isoHdr.sduLen != expIsoLen) + { + LL_TRACE_ERR2("Invalid ISO header: packet length mismatch, expSduLen=%u, actSduLen=%u", expIsoLen, isoHdr.sduLen); + WsfMsgFree(pIsoBuf); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + return; + } + + /*** Resolve ISO context. ***/ + + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(isoHdr.handle)) != NULL) + { + if (!lctrCheckIsCisEstCis(pCisCtx->cisHandle)) + { + LL_TRACE_ERR1("Invalid ISO handle: link not established cisHandle=%u; dropping packet", isoHdr.handle); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + WsfMsgFree(pIsoBuf); + return; + } + + if ((pCisCtx->localDataPdu.maxTxLen == 0) || + ((pCisCtx->bnMToS == 0) && (pCisCtx->role == LL_ROLE_MASTER)) || + ((pCisCtx->bnSToM == 0) && (pCisCtx->role == LL_ROLE_SLAVE))) + { + LL_TRACE_ERR1("Invalid CIS state: handle=%u does not accept transmissions; dropping packet", isoHdr.handle); + WsfMsgFree(pIsoBuf); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + return; + } + + if (pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + lctrIsoSduTxDecAvailBuf(); + + /*** Queue for transmit. ***/ + + lctrCisTxDataPduQueue(pCisCtx, &isoHdr, pIsoBuf); + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + /* Queue up for transmission. */ + WsfMsgEnq(&pCisCtx->isoalTxCtx.pendingSduQ, 0, pIsoBuf); + pCisCtx->isoalTxCtx.pendQueueSize++; + + /* PDU assembly handled in the EndOp. */ + } + } + else if ((pBisCtx = lctrFindBisByHandle(isoHdr.handle)) != NULL) + { + if (isoHdr.sduLen > pBisCtx->pBigCtx->maxSdu) + { + LL_TRACE_ERR2("Invalid ISO header: invalid packet length, actLen=%u, maxSdu=%u", isoHdr.sduLen, pBisCtx->pBigCtx->maxSdu); + WsfMsgFree(pIsoBuf); + lmgrPersistCb.sendCompCback(isoHdr.handle, 1); + return; + } + + lctrIsoSduTxDecAvailBuf(); + + /*** Queue for transmit. ***/ + + if (pBisCtx->pBigCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + lctrBisTxIsoPduQueue(pBisCtx, &isoHdr, pIsoBuf); + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + /* Queue up for transmission. */ + WsfMsgEnq(&pBisCtx->roleData.slv.isoalTxCtx.pendingSduQ, 0, pIsoBuf); + pBisCtx->roleData.slv.isoalTxCtx.pendQueueSize++; + } + } + else + { + LL_TRACE_ERR1("Invalid ISO handle: unknown handle handle=%u; dropping packet", isoHdr.handle); + WsfMsgFree(pIsoBuf); + /* Do not inform host of the number of completed event. */ + } +} + +/*************************************************************************************************/ +/*! + * \brief Receive ISO data path. + * + * \return Received data PDU buffer or NULL if queue empty or data consumed by a data path. + */ +/*************************************************************************************************/ +uint8_t *LctrRxIso(void) +{ + uint8_t *pBuf; + + for (unsigned int i = 0; i < pLctrRtCfg->maxCis; i++) + { + lctrCisCtx_t *pCisCtx = &pLctrCisTbl[i]; + + if ((pCisCtx->enabled) && + ((pBuf = lctrIsoRxConnDeq(&pCisCtx->dataPathOutCtx)) != NULL)) + { + return pBuf; + } + } + + for (unsigned int i = 0; i < pLctrRtCfg->maxBis; i++) + { + lctrBisCtx_t *pBisCtx = &pLctrBisTbl[i]; + + if ((pBisCtx->enabled) && + (pBisCtx->pBigCtx->role == LL_ROLE_MASTER) && + ((pBuf = lctrBisRxIsoSduDeq(pBisCtx)) != NULL)) + { + return pBuf; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief Indicate that received ISO data buffer has been deallocated + * + * \param numBufs Number of completed packets. + * + * Indicate that received ISO data buffer has been deallocated. + */ +/*************************************************************************************************/ +void LctrRxIsoComplete(uint8_t numBufs) +{ + lctrIsoDataRxIncAvailBuf(numBufs); +} + +/*************************************************************************************************/ +/*! + * \brief Used to identify and enable the isochronous data path between the host and the + * controller for each connected isochronous or broadcast isochronous stream. + * + * \param handle BIS or CIS handle. + * \param pPktSn Packet sequence number. + * \param pTs Timestamp. + * \param pTimeOffs Time offset. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrReadIsoTxSync(uint16_t handle, uint16_t *pPktSn, uint32_t *pTs, uint32_t *pTimeOffs) +{ + uint8_t status = LL_SUCCESS; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + lctrCigCtx_t *pCigCtx = lctrFindCigById(pCisCtx->cigId); + + *pPktSn = pCisCtx->cisEvtCounter; + *pTs = pCigCtx->cigBod.dueUsec; + *pTimeOffs = 0; + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + *pPktSn = pBisCtx->pBigCtx->eventCounter * pBisCtx->pBigCtx->bn; + *pTs = pBisCtx->pBigCtx->bod.dueUsec; + *pTimeOffs = 0; + } + else + { + LL_TRACE_WARN1("LctrReadIsoTxSync: handle=%u not found", handle); + status = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used to identify and enable the isochronous data path between the host and the controller for each connected isochronous stream or broadcast isochronous stream. + * + * \param pSetupDataPath Parameters for setup ISO data path. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrSetupIsoDataPath(LlIsoSetupDataPath_t *pSetupDataPath) +{ + uint8_t status = LL_SUCCESS; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + lctrDataPathCtx_t *pDataPathDir; + + if ((pCisCtx = lctrFindCisByHandle(pSetupDataPath->handle)) != NULL) + { + switch (pSetupDataPath->dpDir) + { + case LL_ISO_DATA_DIR_INPUT: + pDataPathDir = (lctrDataPathCtx_t *) (&pCisCtx->dataPathInCtx); + break; + case LL_ISO_DATA_DIR_OUTPUT: + pDataPathDir = (lctrDataPathCtx_t *) (&pCisCtx->dataPathOutCtx); + break; + default: + LL_TRACE_WARN2("LctrSetupIsoDataPath: handle=%u invalid direction dpDir=%u", pSetupDataPath->handle, pSetupDataPath->dpDir); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + return lctrSetupIsoDataPath(pSetupDataPath, pDataPathDir); + } + + else if ((pBisCtx = lctrFindBisByHandle(pSetupDataPath->handle)) != NULL) + { + switch (pSetupDataPath->dpDir) + { + case LL_ISO_DATA_DIR_INPUT: + if (pBisCtx->pBigCtx->role == LL_ROLE_SLAVE) + { + status = lctrBisSetDataPath(pBisCtx, pSetupDataPath->dpDir, pSetupDataPath->dpId); + } + else + { + LL_TRACE_WARN1("LctrSetupIsoDataPath: handle=%u invalid input direction for master", pSetupDataPath->handle); + status = LL_ERROR_CODE_CMD_DISALLOWED; + } + break; + case LL_ISO_DATA_DIR_OUTPUT: + if (pBisCtx->pBigCtx->role == LL_ROLE_MASTER) + { + status = lctrBisSetDataPath(pBisCtx, pSetupDataPath->dpDir, pSetupDataPath->dpId); + } + else + { + LL_TRACE_WARN1("LctrSetupIsoDataPath: handle=%u invalid output direction for slave", pSetupDataPath->handle); + status = LL_ERROR_CODE_CMD_DISALLOWED; + } + break; + default: + break; + } + } + else + { + LL_TRACE_WARN1("LctrSetupIsoDataPath: handle=%u not found", pSetupDataPath->handle); + status = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used to remove the isochronous data path associated with the + * connected isochronous stream or broadcast isochronous stream. + * + * \param handle CIS or BIS handle. + * \param dpDir Direction of data path to remove. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrRemoveIsoDataPath(uint16_t handle, uint8_t dpDir) +{ + uint8_t status = LL_SUCCESS; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + /* Check for validity of parameters before operating on them. */ + if (dpDir | LL_ISO_DATA_PATH_INPUT_BIT) + { + if (pCisCtx->dataPathInCtx.id == LL_ISO_DATA_PATH_DISABLED) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + if (dpDir | LL_ISO_DATA_PATH_OUTPUT_BIT) + { + if (pCisCtx->dataPathOutCtx.id == LL_ISO_DATA_PATH_DISABLED) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + + if (dpDir | LL_ISO_DATA_PATH_INPUT_BIT) + { + pCisCtx->dataPathInCtx.id = LL_ISO_DATA_PATH_DISABLED; + } + if (dpDir | LL_ISO_DATA_PATH_OUTPUT_BIT) + { + pCisCtx->dataPathOutCtx.id = LL_ISO_DATA_PATH_DISABLED; + } + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + pBisCtx->path = LL_ISO_DATA_PATH_DISABLED; + } + else + { + LL_TRACE_WARN1("LctrRemoveIsoDataPath: handle=%u not found", handle); + status = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Tx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload length type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrIsoTxTest(uint16_t handle, uint8_t pldType) +{ + uint8_t status; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + status = lctrCisTxTest(pCisCtx, pldType); + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + status = lctrBisTxTest(pBisCtx, pldType); + } + else + { + LL_TRACE_WARN0("LctrIsoTxTest: handle=%u not found"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload length type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrIsoRxTest(uint16_t handle, uint8_t pldType) +{ + uint8_t status; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + pCisCtx->rxPendInit = (pldType == LL_ISO_TEST_PL_LEN_ZERO) ? FALSE : TRUE; + + pCisCtx->rxTestEnabled = TRUE; + pCisCtx->numRxSuccess = 0; + pCisCtx->numRxMissed = 0; + pCisCtx->numRxFailed = 0; + pCisCtx->isoRxPldType = pldType; + + status = LL_SUCCESS; + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + status = lctrBisRxTest(pBisCtx, pldType); + } + else + { + LL_TRACE_WARN0("LctrIsoRxTest: handle=%u not found"); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief ISO read test counter. + * + * \param handle CIS or BIS handle. + * \param pStats Pointer to the statistics block. + * + * \return Status code. + */ +/*************************************************************************************************/ +uint8_t LctrIsoReadTestCounter(uint16_t handle, LlIsoTestCtrs_t *pStats) +{ + uint8_t status; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + status = LctrCisReadTestCounters(pCisCtx, pStats); + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + status = LctrBisReadTestCounters(pBisCtx, pStats); + } + else + { + LL_TRACE_WARN1("LctrIsoReadTestCounter: handle=%u not found", handle); + status = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Terminate ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pStats Pointer to the statistics block. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrIsoTestEnd(uint16_t handle, LlIsoTestCtrs_t *pStats) +{ + uint8_t status; + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + if (!pCisCtx->rxTestEnabled && + !pCisCtx->txTestEnabled) + { + LL_TRACE_WARN0("Invalid ISO Test state, test mode must be enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if (pCisCtx->rxTestEnabled) + { + status = LctrCisReadTestCounters(pCisCtx, pStats); + pCisCtx->rxTestEnabled = FALSE; + + /* Counters will be reset on re-initialization of Rx test. */ + } + if (pCisCtx->txTestEnabled) + { + pCisCtx->txTestEnabled = FALSE; + } + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + status = LctrBisReadTestCounters(pBisCtx, pStats); + + pBisCtx->test.term = TRUE; + } + else + { + LL_TRACE_WARN1("LctrIsoTestEnd: handle=%u not found", handle); + status = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Read ISO Link Quality action. + * + * \param handle CIS or BIS handle. + * \param pStats Storage for statistics. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LctrReadIsoLinkQual(uint16_t handle, LlIsoLinkQual_t *pStats) +{ + lctrCisCtx_t *pCisCtx; + lctrBisCtx_t *pBisCtx; + if ((pCisCtx = lctrFindCisByHandle(handle)) != NULL) + { + memcpy(pStats, &pCisCtx->isoLinkQualStats, sizeof(LlIsoLinkQual_t)); + return LL_SUCCESS; + } + else if ((pBisCtx = lctrFindBisByHandle(handle)) != NULL) + { + return LL_SUCCESS; + } + else + { + LL_TRACE_WARN1("LctrReadIsoLinkQual: handle=%u not found", handle); + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } +} + +/*************************************************************************************************/ +/*! + * \brief ISO event complete enable. + * + * \param enable Set to TRUE to enable, FALSE to disable. + * + * Enable or disable reports about the scanners from which an advertiser receives scan requests. + */ +/*************************************************************************************************/ +void LlIsoEventCompleteEnable(uint8_t enable) +{ + lmgrCb.sendIsoCmplEvt = enable; +} + +/*************************************************************************************************/ +/*! + * \brief Notify host ISO Event completion. + * + * \param handle CIG or BIG Handle. + * \param evtCtr Event Counter. + */ +/*************************************************************************************************/ +void lctrNotifyHostIsoEventComplete(uint8_t handle, uint32_t evtCtr) +{ + LlIsoEventCmplInd_t evt; + + evt.hdr.param = handle; + evt.hdr.event = LL_ISO_EVT_CMPL_IND; + evt.hdr.status = LL_SUCCESS; + + evt.handle = handle; + evt.evtCtr = evtCtr; + + LL_TRACE_INFO1("### LlEvent ### LL_ISO_EVT_CMPL_IND, handle=%u", handle); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Send Codec SDU data. + * + * \param handle Stream ID. + */ +/*************************************************************************************************/ +void lctrIsoSendCodecSdu(uint16_t handle) +{ + lctrBisCtx_t *pBisCtx; + + if ((pBisCtx = lctrFindBisByHandle(handle)) == NULL) + { + LL_TRACE_WARN1("lctrIsoSendCodecSdu: handle=%u not found", handle); + return; + } + + uint8_t *pSduBuf; + + if ((pSduBuf = WsfMsgAlloc(pLctrRtCfg->maxIsoSduLen + HCI_ISO_DL_MAX_LEN)) == NULL) + { + LL_TRACE_ERR1("!!! Out of memory; dropping input SDU, stream=%u", handle); + return; + } + + uint16_t len; + uint32_t pktCtr; + + WSF_ASSERT(lctrCodecHdlr.in); + if ((len = lctrCodecHdlr.in(handle, pSduBuf + HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN, + pBisCtx->pBigCtx->maxSdu, &pktCtr)) == 0) + { + LL_TRACE_WARN1("ISO audio stream data not available, stream=%u", handle); + WsfMsgFree(pSduBuf); + return; + } + + lctrIsoHdr_t hdr = + { + .handle = handle, + .pb = LCTR_PB_COMP, + .tsFlag = TRUE, + .len = len, + .ts = 0, + .pktSn = pktCtr, + .sduLen = len, + .ps = LCTR_PS_VALID + }; + + lctrIsoPackHdr(pSduBuf, &hdr); + LctrTxIso(pSduBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Setup ISO data path. + * + * \param pSetupDataPath Data path setup parameters. + * \param pDataPathCtx Generic data path context. + */ +/*************************************************************************************************/ +uint8_t lctrSetupIsoDataPath(LlIsoSetupDataPath_t *pSetupDataPath, lctrDataPathCtx_t *pDataPathCtx) +{ + switch (pSetupDataPath->dpDir) + { + case LL_ISO_DATA_DIR_INPUT: + { + if (pSetupDataPath->dpId == pDataPathCtx->in.id) + { + return LL_SUCCESS; + } + + /* No teardown needed. */ + pDataPathCtx->in.id = pSetupDataPath->dpId; + /* No setup needed. */ + break; + } + + case LL_ISO_DATA_DIR_OUTPUT: + { + if (pSetupDataPath->dpId == pDataPathCtx->out.id) + { + return LL_SUCCESS; + } + + lctrIsoOutDataPathClear(&pDataPathCtx->out); + pDataPathCtx->out.id = pSetupDataPath->dpId; + lctrIsoOutDataPathSetup(&pDataPathCtx->out); + break; + } + + default: + LL_TRACE_ERR1("Invalid value dpDir=%u", pSetupDataPath->dpDir); + break; + } + + return LL_SUCCESS; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso_data.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso_data.c new file mode 100644 index 00000000000..424a2ee5895 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_iso_data.c @@ -0,0 +1,1181 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller data path implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_iso.h" +#include "lctr_pdu_iso.h" +#include "lctr_int_cis.h" +#include "ll_math.h" +#include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include "hci_defs.h" +#include "pal_bb.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Free list of Tx buffer descriptors. */ +static wsfQueue_t lctrIsoTxBufDescQ; + +/*! \brief Completed transmit buffer. */ +static uint8_t *pLctrTxCompBuf; + +/*! \brief Completed transmit buffer handle ID. */ +static wsfHandlerId_t lctrTxCompBufHandlerId; + +/*************************************************************************************************/ +/*! + * \brief Assemble CIS Data PDU. + * + * \param pIsoHdr ISO header. + * \param pBuf Buffer to pack the Data PDU header. + * \param llid CIS LLID + */ +/*************************************************************************************************/ +static void lctrAssembleCisDataPdu(lctrIsoHdr_t *pIsoHdr, uint8_t *pBuf, uint8_t llid) +{ + /* All additional fields must be zero'ed since flow control bits will be or'ed in at transmit. */ + lctrCisDataPduHdr_t dataHdr = { 0 }; + + dataHdr.llid = llid; + dataHdr.len = pIsoHdr->sduLen; + + lctrCisPackDataPduHdr(pBuf, &dataHdr); +} + + +/*************************************************************************************************/ +/*! + * \brief Initialize the transmit memory resources. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + */ +/*************************************************************************************************/ +uint16_t lctrIsoTxInitMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + pLctrTxCompBuf = NULL; + + WSF_ASSERT(pLctrRtCfg->numIsoTxBuf); + WSF_ASSERT(pLctrRtCfg->maxIsoSduLen); + + uint8_t *pAvailMem = pFreeMem; + + const uint16_t descSize = sizeof(lctrIsoTxBufDesc_t) + (LL_MAX_FRAG * sizeof(((lctrIsoTxBufDesc_t *)0)->frag[0])); + + LL_TRACE_INFO2(" RAM: %u x %u bytes -- Tx buffer descriptors", pLctrRtCfg->numIsoTxBuf, sizeof(void *) + descSize); + + lctrIsoTxBufDescQ.pHead = NULL; + lctrIsoTxBufDescQ.pTail = NULL; + + unsigned int i; + + for (i = 0; i < pLctrRtCfg->numIsoTxBuf; i++) + { + lctrIsoTxBufDesc_t *pDesc; + + if (((uint32_t)pAvailMem) & 3) + { + /* Align to next word. */ + pAvailMem = (uint8_t *)(((uint32_t)pAvailMem & ~3) + sizeof(uint32_t)); + } + + /* Allocate memory. */ + pDesc = (lctrIsoTxBufDesc_t *)pAvailMem; + pAvailMem += (2 * sizeof(uint32_t)) + descSize; /* wsfMsg_t header is at most 2 words */ + + if (((uint32_t)(pAvailMem - pFreeMem)) > freeMemSize) + { + return 0; + } + + /* Add to free list. */ + WsfQueueEnq(&lctrIsoTxBufDescQ, pDesc); + } + + return (pAvailMem - pFreeMem); +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a Tx buffer descriptor. + * + * \return A Tx buffer descriptor, NULL if allocation fails. + */ +/*************************************************************************************************/ +lctrIsoTxBufDesc_t *lctrAllocIsoTxBufDesc(void) +{ + uint8_t *pElem; + + if ((pElem = WsfQueueDeq(&lctrIsoTxBufDescQ)) == NULL) + { + return NULL; + } + + pElem += (2 * sizeof(uint32_t)); /* hide header */ + + return (lctrIsoTxBufDesc_t *)pElem; +} + +/*************************************************************************************************/ +/*! + * \brief Free a Tx buffer descriptor. + * + * \param pDesc Pointer to a Tx buffer descriptor. + */ +/*************************************************************************************************/ +void lctrFreeIsoTxBufDesc(lctrIsoTxBufDesc_t *pDesc) +{ + uint8_t *pElem = (uint8_t *)pDesc; + pElem -= (2 * sizeof(uint32_t)); /* recover header */ + + WsfQueueEnq(&lctrIsoTxBufDescQ, pElem); +} + +/*************************************************************************************************/ +/*! + * \brief Queue data PDU onto ARQ queue. + * + * \param pCisCtx CIS context. + * \param pIsoHdr ISO header. + * \param pIsoBuf ISO buffer. + */ +/*************************************************************************************************/ +void lctrCisTxDataPduQueue(lctrCisCtx_t *pCisCtx, lctrIsoHdr_t *pIsoHdr, uint8_t *pIsoBuf) +{ + uint16_t fragOffset = 0; + uint16_t isoLen = pIsoHdr->sduLen; + uint16_t fragLen = pCisCtx->localDataPdu.maxTxLen; + + lctrIsoTxBufDesc_t *pDesc; + + if ((pDesc = lctrAllocIsoTxBufDesc()) == NULL) + { + LL_TRACE_ERR1("Failed to allocate transmit buffer descriptor: cisHandle=%u", pIsoHdr->handle); + WsfMsgFree(pIsoBuf); + if (pCisCtx->txTestEnabled == FALSE) + { + uint16_t handle = pIsoHdr->handle; + uint16_t numSdu = 1; + lmgrPersistCb.sendIsoCompCback(1, &handle, &numSdu); + } + lctrIsoSduTxIncAvailBuf(); + + lctrNotifyHostHwErrInd(LL_ERROR_CODE_MEM_CAP_EXCEEDED); + return; + } + + if (fragLen >= pIsoHdr->sduLen) + { + fragLen = pIsoHdr->sduLen; + } + + pDesc->isoLen = pIsoHdr->sduLen; + pDesc->fragLen = fragLen; + pDesc->fragCnt = 0; + + /* Get the start of the buffer. */ + pDesc->pIsoSdu = pIsoBuf; + pIsoBuf += LCTR_GET_ISO_DATA_HDR_LEN(pIsoHdr); + pDesc->pPduBuf = pIsoBuf; + uint8_t fragCnt = 0; + + uint8_t llid; + + do + { + const uint16_t dataRem = isoLen - fragOffset; + const uint16_t fragSize = WSF_MIN(dataRem, fragLen); + + if (pCisCtx->framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + llid = (fragSize == dataRem) ? LL_LLID_ISO_UNF_END_PDU : LL_LLID_ISO_UNF_CONT_PDU; + } + else + { + llid = LL_LLID_ISO_FRA_PDU; + } + + pIsoHdr->sduLen = fragSize; + lctrAssembleCisDataPdu(pIsoHdr, pDesc->frag[fragCnt].hdr, llid); + pDesc->frag[fragCnt].hdrLen = LL_DATA_HDR_LEN; + + if (lctrPktEncryptHdlr && lctrPktEncryptHdlr(&pCisCtx->bleData.chan.enc, pDesc->frag[fragCnt].hdr, pIsoBuf, pDesc->frag[fragCnt].trl)) + { + pDesc->frag[fragCnt].trlLen = LL_DATA_MIC_LEN; + + #if (LL_ENABLE_TESTER) + pDesc->frag[fragCnt].trl[0] ^= (llTesterCb.pktMic >> 0) & 0xFF; + pDesc->frag[fragCnt].trl[1] ^= (llTesterCb.pktMic >> 8) & 0xFF; + pDesc->frag[fragCnt].trl[2] ^= (llTesterCb.pktMic >> 16) & 0xFF; + pDesc->frag[fragCnt].trl[3] ^= (llTesterCb.pktMic >> 24) & 0xFF; + #endif + } + else + { + pDesc->frag[fragCnt].trlLen = 0; + } + + fragOffset += fragSize; + pIsoBuf += fragSize; + fragCnt++; + } + while (fragOffset < isoLen); + + WsfMsgEnq(&pCisCtx->txArqQ, pIsoHdr->handle, (uint8_t *)pDesc); +} + +/*************************************************************************************************/ +/*! + * \brief Get top element in Tx queue. + * + * \param pCisCtx CIS context. + * \param pDescs Storage for BB descriptors. + * + * \return Number of BB descriptors. + */ +/*************************************************************************************************/ +uint8_t lctrCisTxQueuePeek(lctrCisCtx_t *pCisCtx, PalBbBleTxBufDesc_t *pDescs) +{ + wsfHandlerId_t handlerId; + uint8_t *pTxBuf; + uint8_t descCnt = 0; + + /* Do not remove from ARQ until acknowledged by peer. */ + pTxBuf = WsfMsgPeek(&pCisCtx->txArqQ, &handlerId); + if (pTxBuf != NULL) + { + /*** Send Data PDU ***/ + + lctrIsoTxBufDesc_t *pDesc = (lctrIsoTxBufDesc_t *)pTxBuf; + uint8_t fragCnt = pDesc->fragCnt; + uint16_t fragSize = pDesc->fragLen; + uint16_t fragOff = fragSize * fragCnt; + + if ((fragOff + fragSize) > pDesc->isoLen) + { + fragSize = pDesc->isoLen - fragOff; + } + pDescs[0].len = pDesc->frag[fragCnt].hdrLen; + pDescs[0].pBuf = pDesc->frag[fragCnt].hdr; + pDescs[1].len = fragSize; + pDescs[1].pBuf = pDesc->pPduBuf + fragOff; + descCnt = 2; + if (pDesc->frag[fragCnt].trlLen) + { + pDescs[2].len = pDesc->frag[fragCnt].trlLen; + pDescs[2].pBuf = pDesc->frag[fragCnt].trl; + descCnt = 3; + } + } + + return descCnt; +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element from Tx queue. + * + * \param pCisCtx CIS context. + * + * \return TRUE if element popped. + */ +/*************************************************************************************************/ +bool_t lctrCisTxQueuePop(lctrCisCtx_t *pCisCtx) +{ + wsfHandlerId_t handlerId; + uint8_t *pBuf; + + WSF_ASSERT(pLctrTxCompBuf == NULL); + + /* Remove last transmitted PDU. */ + if ((pBuf = WsfMsgPeek(&pCisCtx->txArqQ, &handlerId)) != NULL) + { + lctrIsoTxBufDesc_t *pDesc = (lctrIsoTxBufDesc_t *)pBuf; + uint16_t fragSize = pDesc->fragLen; + + if ((fragSize * (pDesc->fragCnt + 1)) >= pDesc->isoLen) /* last fragment */ + { + /* Store buffer for post setup cleanup. */ + pLctrTxCompBuf = pBuf; + lctrTxCompBufHandlerId = handlerId; + + WsfMsgDeq(&pCisCtx->txArqQ, &handlerId); + } + else + { + /* Move to next fragment. */ + pDesc->fragCnt++; + } + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Pop top element from Tx queue. + * + * \param pCisCtx Connection context. + */ +/*************************************************************************************************/ +void lctrCisTxQueuePopCleanup(lctrCisCtx_t *pCisCtx) +{ + if (pLctrTxCompBuf) + { + lctrIsoTxBufDesc_t *pDesc = (lctrIsoTxBufDesc_t *)pLctrTxCompBuf; + + WsfMsgFree(pDesc->pIsoSdu); + lctrFreeIsoTxBufDesc(pDesc); + lctrIsoSduTxIncAvailBuf(); + pCisCtx->numTxComp++; + + pLctrTxCompBuf = NULL; + + WsfSetEvent(lmgrPersistCb.handlerId, (1 << LCTR_EVENT_ISO_TX_COMPLETE)); + } +} + +/*************************************************************************************************/ +/*! + * \brief Clear Tx queue. + * + * \param pCisCtx CIS context. + * + * \return Number of freed buffers. + */ +/*************************************************************************************************/ +uint8_t lctrCisTxQueueClear(lctrCisCtx_t *pCisCtx) +{ + uint8_t *pBuf; + uint8_t numTxBufs = 0; + wsfHandlerId_t handlerId; + + /* Clear the pending Tx buffer. */ + if (pLctrTxCompBuf) + { + lctrCisTxQueuePopCleanup(pCisCtx); + } + + /* Clear the rest of the Tx buffer. */ + while ((pBuf = WsfMsgDeq(&pCisCtx->txArqQ, &handlerId)) != NULL) + { + lctrIsoTxBufDesc_t *pDesc = (lctrIsoTxBufDesc_t *)pBuf; + + WsfMsgFree(pDesc->pIsoSdu); + + lctrFreeIsoTxBufDesc(pDesc); + + lctrIsoSduTxIncAvailBuf(); + numTxBufs++; + } + + return numTxBufs; +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a receive data PDU buffer. + * + * \param maxRxLen Maximum receive length. + * + * \return Pointer to the start of the PDU data buffer. + */ +/*************************************************************************************************/ +uint8_t *lctrCisRxPduAlloc(uint16_t maxRxLen) +{ + /* LCTR_DATA_PDU_MAX_LEN includes LL_DATA_MIC_LEN if required. */ + const uint16_t allocLen = WSF_MAX(BB_FIXED_DATA_PKT_LEN, LCTR_CIS_DATA_PDU_LEN(maxRxLen)) + LCTR_CIS_DATA_PDU_START_OFFSET; + + uint8_t *pBuf; + + /* Include ISO header. */ + if ((pBuf = WsfMsgAlloc(HCI_ISO_DL_MAX_LEN + allocLen)) != NULL) + { + /* Return start of data PDU. */ + pBuf += LCTR_CIS_DATA_PDU_START_OFFSET + HCI_ISO_DL_MAX_LEN; + } + + return pBuf; +} + +/*************************************************************************************************/ +/*! + * \brief Free a receive CIS data PDU buffer. + * + * \param pBuf PDU data buffer to free. + */ +/*************************************************************************************************/ +void lctrCisRxPduFree(uint8_t *pBuf) +{ + /* Recover headroom, assume buffer starts at the beginning of the data PDU. */ + pBuf -= (LCTR_CIS_DATA_PDU_START_OFFSET + HCI_ISO_DL_MAX_LEN); + + WsfMsgFree(pBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Enqueue a receive data PDU buffer. + * + * \param pBuf PDU data buffer to queue. + * \param eventCounter Event counter. + * \param cisHandle Connection handle. + */ +/*************************************************************************************************/ +void lctrCisRxEnq(uint8_t *pBuf, uint16_t eventCounter, uint16_t cisHandle) +{ + /* Stamp packet with event counter. */ + pBuf -= LCTR_CIS_DATA_PDU_START_OFFSET; + UINT16_TO_BUF(pBuf, eventCounter); + + /* Queue LE Data PDU. */ + WsfMsgEnq(&lmgrIsoCb.rxDataQ, cisHandle, pBuf); + WsfSetEvent(lmgrPersistCb.handlerId, (1 << LCTR_EVENT_CIS_RX_PENDING)); +} + +/*************************************************************************************************/ +/*! + * \brief Dequeue a receive data PDU buffer. + * + * \param pCisHandle Storage for connection handle. + * + * \return Pointer to the start of the PDU data buffer. + */ +/*************************************************************************************************/ +uint8_t *lctrCisRxDeq(uint16_t *pCisHandle) +{ + uint8_t *pBuf; + wsfHandlerId_t handlerId; + + if ((pBuf = WsfMsgDeq(&lmgrIsoCb.rxDataQ, &handlerId)) != NULL) + { + /* Return start of data PDU. */ + pBuf += LCTR_CIS_DATA_PDU_START_OFFSET; + + *pCisHandle = (uint16_t)handlerId; + } + + return pBuf; +} + +/*************************************************************************************************/ +/*! + * \brief Enqueue a receive data PDU buffer for a connection as a ISO message. + * + * \param pOutDataPathCtx Datapath output context. + * \param handle ISO handle. + * \param pBuf SDU buffer. + * + * \return TRUE if buffer successfully handled and will be used. + * FALSE if buffer was not handled and needs to be disposed. + * + */ +/*************************************************************************************************/ +bool_t lctrIsoRxConnEnq(lctrOutDataPathCtx_t *pOutDataPathCtx, uint16_t handle, uint8_t *pBuf) +{ + switch (pOutDataPathCtx->id) + { + case LL_ISO_DATA_PATH_HCI: + WsfMsgEnq(&pOutDataPathCtx->cfg.hci.rxDataQ, handle, pBuf); + pOutDataPathCtx->cfg.hci.numRxPend++; + /* TODO optimize counter, accounting upon allocation. */ + lctrIsoDataRxDecAvailBuf(); + return TRUE; + + case LL_ISO_DATA_PATH_VS: + default: + return FALSE; + } +} + +/*************************************************************************************************/ +/*! + * \brief Dequeue a receive data PDU buffer for a connection as a ISO message. + * + * \param pOutCtx Output context. + * + * \return Pointer to the start of the ISO message. + * + * \note Returned pointer must be freed with WsfMsgFree(). + */ +/*************************************************************************************************/ +uint8_t *lctrIsoRxConnDeq(lctrOutDataPathCtx_t *pOutCtx) +{ + wsfHandlerId_t handle; + + if (pOutCtx->id != LL_ISO_DATA_PATH_HCI) + { + return NULL; + } + + return WsfMsgDeq(&pOutCtx->cfg.hci.rxDataQ, &handle); +} + +/*************************************************************************************************/ +/*! + * \brief Setup a datapath context. + * + * \param pOutCtx Output datapath context. + */ +/*************************************************************************************************/ +void lctrIsoOutDataPathSetup(lctrOutDataPathCtx_t *pOutCtx) +{ + switch (pOutCtx->id) + { + case LL_ISO_DATA_PATH_HCI: + pOutCtx->cfg.hci.numRxPend = 0; + WSF_QUEUE_INIT(&pOutCtx->cfg.hci.rxDataQ); + break; + + case LL_ISO_DATA_PATH_VS: + /* No action. */ + break; + + default: + /* No action. */ + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Clear a datapath context. + * + * \param pOutCtx Output datapath context. + */ +/*************************************************************************************************/ +void lctrIsoOutDataPathClear(lctrOutDataPathCtx_t *pOutCtx) +{ + switch (pOutCtx->id) + { + case LL_ISO_DATA_PATH_HCI: + { + uint8_t *pBuf; + wsfHandlerId_t handlerId; + while ((pBuf = WsfMsgDeq(&pOutCtx->cfg.hci.rxDataQ, &handlerId)) != NULL) + { + WsfMsgFree(pBuf); + lctrIsoDataRxIncAvailBuf(1); + } + break; + } + + case LL_ISO_DATA_PATH_VS: + /* No action. */ + break; + + default: + /* No action. */ + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Clear a ISOAL receive context. + * + * \param pRxCtx ISOAL receive context + * \param framing Framing scheme. + */ +/*************************************************************************************************/ +void lctrIsoalRxDataPathClear(lctrIsoalRxCtx_t *pRxCtx, uint8_t framing) +{ + uint8_t *pSduBuf; + uint8_t handlerId; + if (framing == LL_ISO_PDU_TYPE_UNFRAMED) + { + while ((pSduBuf = WsfMsgDeq(&pRxCtx->data.unframed.pendSduQ, &handlerId)) != NULL) + { + WsfMsgFree(pSduBuf); + } + } + else /* LL_ISO_PDU_TYPE_FRAMED */ + { + if (pRxCtx->pPendSduBuf) + { + WsfMsgFree(pRxCtx->pPendSduBuf); + pRxCtx->pPendSduBuf = NULL; + } + } + + pRxCtx->pduFlushed = FALSE; + pRxCtx->rxState = LL_ISO_SDU_STATE_NEW; +} + +/*************************************************************************************************/ +/*! + * \brief Generate transmit ISO test data. + * + * \param handle Connection handle. + * \param pldType Payload length type. + * \param maxSdu Max SDU length. + * \param pktCtr Packet counter. + * + * \return Pointer to an HCI ISO SDU. + * + * Initialization of ISO test data will allocate and fill a ISO SDU to accommodate any payload + * type. The LL will modify the length and payload (i.e. Packet Counter) as needed. + */ +/*************************************************************************************************/ +uint8_t *lctrGenerateIsoTestData(uint16_t handle, LlIsoPldType_t pldType, uint16_t maxSdu, uint32_t pktCtr) +{ + uint8_t *pSdu; + + if ((pSdu = lctrTxIsoDataPduAlloc()) == NULL) + { + LL_TRACE_WARN0("!!! Failed to generate a ISO Test Data SDU"); + return NULL; + } + + uint8_t *pBuf = pSdu; + uint16_t len; + + switch (pldType) + { + case LL_ISO_PLD_TYPE_VAR_LEN: + len = LlMathRandNum() % maxSdu; /* TODO Use portable mod routine */ + /* Ensure minimum SDU length includes mandatory payload. */ + len = WSF_MAX(len, sizeof(uint32_t)); + break; + + case LL_ISO_PLD_TYPE_MAX_LEN: + /* Ensure minimum SDU length includes mandatory payload. */ + len = WSF_MAX(maxSdu, sizeof(uint32_t)); + break; + + case LL_ISO_PLD_TYPE_ZERO_LEN: + len = 0; + break; + + default: + { + LL_TRACE_ERR1("Invalid value pldType=%u", pldType); + len = 0; + break; + } + } + + /* Pack ISO header. */ + lctrIsoHdr_t isoHdr; + + isoHdr.handle = handle; + isoHdr.pb = LCTR_PB_COMP; + isoHdr.tsFlag = 0; + isoHdr.len = len; + isoHdr.pktSn = 0; + isoHdr.sduLen = len; + isoHdr.ps = LCTR_PS_VALID; + + pBuf += lctrIsoPackHdr(pBuf, &isoHdr); + + if (len > 0) + { + /* Fill mandatory payload (do not advance pBuf). */ + UINT32_TO_BUF(pBuf, pktCtr); + + /* Fill VS payload (byte content is offset number). */ + for (unsigned int i = sizeof(uint32_t); i < len; i++) + { + pBuf[i] = i; + } + } + + return pSdu; +} + +/*************************************************************************************************/ +/*! + * \brief Validate received ISO test data. + * + * \param pPld Payload start buffer. + * \param actLen Length of payload + * \param pRxStats Rx statistics. + * \param pldType Payload length type. + * \param expMaxSdu Expected max SDU length. + * \param expPldCtr Expected payload counter. + */ +/*************************************************************************************************/ +void lctrValidateIsoTestData(uint8_t *pPld, uint8_t actLen, LlIsoTestCtrs_t *pRxStats, uint8_t pldType, uint16_t expMaxSdu, uint32_t expPldCtr) +{ + uint32_t actPldCtr; + + /* Parse transmitted payload counter. */ + switch (pldType) + { + case LL_ISO_PLD_TYPE_VAR_LEN: + case LL_ISO_PLD_TYPE_MAX_LEN: + BSTREAM_TO_UINT32(actPldCtr, pPld); + break; + case LL_ISO_PLD_TYPE_ZERO_LEN: + default: + actPldCtr = 0; + break; + } + + /* Validate received SDU. */ + switch (pldType) + { + case LL_ISO_PLD_TYPE_ZERO_LEN: + if (actLen != 0) + { + LL_TRACE_WARN1("lctrValidateIsoTestData: wrong length, actLen=%u expLen=0", actLen); + pRxStats->numFailed++; + } + else + { + pRxStats->numSuccess++; + } + break; + case LL_ISO_PLD_TYPE_VAR_LEN: + if ((actLen < sizeof(uint32_t)) || (actLen > expMaxSdu)) + { + LL_TRACE_WARN2("lctrValidateIsoTestData: wrong length, actLen=%u expLen=[0..%u]", actLen, expMaxSdu); + pRxStats->numFailed++; + } + else if (actPldCtr != expPldCtr) + { + LL_TRACE_WARN2("lctrValidateIsoTestData: wrong payload counter, actPldCtr[15:0]=%u expPldCtr[15:0]=%u", actPldCtr, expPldCtr); + pRxStats->numFailed++; + } + else + { + pRxStats->numSuccess++; + } + break; + case LL_ISO_PLD_TYPE_MAX_LEN: + if (actLen != expMaxSdu) + { + LL_TRACE_WARN2("lctrValidateIsoTestData: wrong length, actLen=%u expLen=%u", actLen, expMaxSdu); + pRxStats->numFailed++; + } + else if (actPldCtr != expPldCtr) + { + LL_TRACE_WARN2("lctrValidateIsoTestData: wrong payload counter, actPldCtr[15:0]=%u expPldCtr[15:0]=%u", actPldCtr, expPldCtr); + pRxStats->numFailed++; + } + else + { + pRxStats->numSuccess++; + } + break; + default: + LL_TRACE_WARN1("lctrValidateIsoTestData: invalid parameter, pldType=%u", pldType); + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a transmit ISO Data PDU buffer. + * + * \return Pointer to the start of the ISO Data PDU buffer, NULL if allocation failed. + */ +/*************************************************************************************************/ +uint8_t *lctrTxIsoDataPduAlloc(void) +{ + uint8_t *pPdu; + + const uint32_t allocLen = HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN + pLctrRtCfg->maxIsoSduLen + BB_DATA_PDU_TAILROOM; + + /* Use LL_ISO_PDU_MAX_LEN to ensure use of data buffers located in the large pool. */ + if ((pPdu = (uint8_t*)WsfMsgAlloc(allocLen)) == NULL) + { + LL_TRACE_WARN1("lctrTxIsoDataPduAlloc: Unable to allocate framed Tx buffer, allocSize=%u", allocLen); + } + + return pPdu; +} + +/*************************************************************************************************/ +/*! + * \brief Assemble framed PDU. + * + * \param pIsoalTxCtx Transmit ISOAL context. + * \param pPduBuf PDU buffer. + * \param maxPduLen Maximum PDU length. + * + * \return Total size of assembled PDU. + */ +/*************************************************************************************************/ +uint8_t lctrAssembleTxFramedPdu(lctrIsoalTxCtx_t *pIsoalTxCtx, uint8_t *pPduBuf, uint16_t maxPduLen) +{ + wsfQueue_t *pSduQ = &pIsoalTxCtx->pendingSduQ; + + uint8_t handlerId; /* Temp variable for the wsfMsg. */ + uint8_t totalTx = 0; + uint16_t remLen = maxPduLen; + lctrIsoSegHdr_t segHdr = { 0 }; + uint8_t segHdrLen = 0; + uint8_t *pFreeData = NULL; + + /* Set offset of pPduBuf */ + pPduBuf += HCI_ISO_HDR_LEN + HCI_ISO_DL_MIN_LEN; + + /*** Loop through and pack SDUs. ***/ + + while (remLen) + { + uint8_t *pSduBuf = WsfMsgPeek(pSduQ, &handlerId); + + /* The buffer is empty, process the completed PDU */ + if (pSduBuf == NULL) + { + break; + } + + lctrIsoHdr_t isoHdr; + + /*** Disassemble ISO packet. ***/ + + lctrIsoUnpackHdr(&isoHdr, pSduBuf); + + pSduBuf += LCTR_GET_ISO_DATA_HDR_LEN(&isoHdr); + segHdrLen = LL_DATA_HDR_LEN; + + /* If this is a segmented SDU, continue from the last segment. */ + if (pIsoalTxCtx->sduOffset) + { + /* Resume buffer at sduOffset. */ + pSduBuf += pIsoalTxCtx->sduOffset; + isoHdr.sduLen -= pIsoalTxCtx->sduOffset; + + /* Set continuation bit. */ + segHdr.sc = 1; + } + else + { + segHdr.sc = 0; + segHdrLen += LL_ISO_SEG_TO_LEN; + } + + /*** Compute segment parameters. ***/ + + /* There is enough room for the entire SDU. */ + if (remLen >= (isoHdr.sduLen + segHdrLen)) + { + segHdr.len = isoHdr.sduLen; + segHdr.cmplt = 1; + if (segHdr.sc == 0) + { + /* TODO: put in time offset. */ + segHdr.toffs = 0x1337; + } + + /* Reset pduOffset and update remaining length. */ + pIsoalTxCtx->sduOffset = 0; + remLen -= segHdr.len + segHdrLen; + + /* Pop off completed SDU. */ + pFreeData = WsfMsgDeq(pSduQ, &handlerId); + pIsoalTxCtx->pendQueueSize--; + pIsoalTxCtx->compSdu++; + } + else + { + /* If it cannot fit at least one effective (data) byte, finish packing here. */ + if (remLen < (segHdrLen + 1)) + { + break; + } + + segHdr.len = remLen - segHdrLen; + segHdr.cmplt = 0; + if (segHdr.sc == 0) + { + /* TODO: put in time offset. */ + segHdr.toffs = 0x1337; + } + + /* Save offset. */ + pIsoalTxCtx->sduOffset += segHdr.len; + remLen = 0; /* We filled as much as we can, no need to track it anymore. */ + } + + /*** Pack PDU ***/ + + /* Pack buffer with seg header */ + pPduBuf += lctrIsoPackSegHdr(pPduBuf, &segHdr); + + /* Pack data into buffer. */ + uint8_t sduDataLen = segHdr.len; + memcpy(pPduBuf, pSduBuf, sduDataLen); + pPduBuf += sduDataLen; + + /* Free buffer. */ + if (pFreeData) + { + WsfMsgFree(pFreeData); + pFreeData = NULL; + } + + totalTx += sduDataLen + segHdrLen; + } + + return totalTx; +} + +/*************************************************************************************************/ +/*! + * \brief Allocate a receive ISO SDU buffer. + * + * \return Pointer to the start of the ISO Data PDU buffer, NULL if allocation failed. + */ +/*************************************************************************************************/ +static uint8_t *lctrRxSduAlloc(void) +{ + uint8_t *pSdu; + + const uint32_t allocLen = HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN + pLctrRtCfg->maxIsoSduLen + BB_DATA_PDU_TAILROOM; + + /* Use LL_ISO_PDU_MAX_LEN to ensure use of data buffers located in the large pool. */ + if ((pSdu = (uint8_t*)WsfMsgAlloc(allocLen)) != NULL) + { + lctrIsoDataRxDecAvailBuf(); + } + + return pSdu; +} + +/*************************************************************************************************/ +/*! + * \brief Queue the received SDU into the pending queue. + * + * \param pRxCtx ISOAL receive context. + * \param pSdu SDU buffer. + * \param handle CIS connection handle. + * \param dataLen Data length. + * \param llid Rx LLID. + * + * \return TRUE if pending queue ready to be sent to host. + */ +/*************************************************************************************************/ +bool_t lctrIsoUnframedRxSduPendQueue(lctrIsoalRxCtx_t *pRxCtx, uint8_t *pSdu, uint16_t handle, + uint16_t dataLen, uint8_t llid) +{ + /* Save data for head packet. */ + /* pRxCtx->data.unframed.pendSduIsoHdr.ps = 0; */ /* Should be done in calling function. */ + pRxCtx->data.unframed.curLen += dataLen; + + WsfMsgEnq(&pRxCtx->data.unframed.pendSduQ, handle, pSdu); + + /* If we received the last PDU, pack the head packet with the packet status and sdu length. */ + if (llid == LL_LLID_ISO_UNF_END_PDU) + { + uint8_t *pHeadPkt; + uint8_t handlerId; + lctrIsoHdr_t isoHdr = {0}; + + pHeadPkt = WsfMsgPeek(&pRxCtx->data.unframed.pendSduQ, &handlerId); + WSF_ASSERT(pHeadPkt); + + lctrIsoUnpackHdr(&isoHdr, pHeadPkt); + isoHdr.pktSn = pRxCtx->packetSequence++; + isoHdr.sduLen = pRxCtx->data.unframed.curLen; + isoHdr.ps = pRxCtx->data.unframed.ps; + isoHdr.len -= + HCI_ISO_DL_MAX_LEN; + + /* Reset the packet boundary in case a missed packet leaves it undefined. */ + uint8_t rfu; /* Used to peek into msg queue. */ + if (WsfMsgNPeek(&pRxCtx->data.unframed.pendSduQ, 1, &rfu)) + { + isoHdr.pb = LCTR_PB_FIRST; + } + else + { + isoHdr.pb = LCTR_PB_COMP; + } + + lctrIsoPackHdr(pHeadPkt, &isoHdr); + + /* Clean up context */ + pRxCtx->data.unframed.curLen = 0; + pRxCtx->data.unframed.ps = 0; + return TRUE; + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Assemble received framed SDU(s) from PDU. + * + * \param pIsoalRxCtx Receive ISOAL control block. + * \param pRxQueue Receive queue. + * \param handle CIS/BIS Handle. + * \param pIsoBuf ISO data buffer. + * \param len Length of data buffer. + * + * \return Total number of SDUs queued. + */ +/*************************************************************************************************/ +uint8_t lctrAssembleRxFramedSdu(lctrIsoalRxCtx_t *pIsoalRxCtx, wsfQueue_t *pRxQueue, + uint16_t handle, uint8_t *pIsoBuf, uint8_t len) +{ + uint8_t totalSduQueued = 0; + + /* Last PDU was flushed. SDU data is lost and will be flushed. */ + if (pIsoalRxCtx->pduFlushed) + { + if (pIsoalRxCtx->pPendSduBuf) + { + /* Flush SDU. */ + WsfMsgFree(pIsoalRxCtx->pPendSduBuf); + pIsoalRxCtx->pPendSduBuf = NULL; + } + pIsoalRxCtx->pduFlushed = FALSE; + return 0; + } + + uint8_t *pDataBuf = pIsoBuf + LL_DATA_HDR_LEN; + uint8_t *pSduBuf; + + uint8_t remLen = len; + + lctrIsoSegHdr_t segHdr = { 0 }; + + while (remLen > 0) + { + uint8_t hdrLen = lctrIsoUnpackSegHdr(&segHdr, pDataBuf); + pDataBuf += hdrLen; + + if (segHdr.sc == 0) + { + segHdr.len -= LL_ISO_SEG_TO_LEN; + } + + switch (pIsoalRxCtx->rxState) + { + case LL_ISO_SDU_STATE_NEW: + { + if ((pIsoalRxCtx->pPendSduBuf = lctrRxSduAlloc()) == NULL) + { + LL_TRACE_WARN1("Unable to allocate framed Rx buffer, handle=%u", handle); + continue; + } + + /* Move pointer to start of data buffer. */ + pIsoalRxCtx->rxSduOffset = LCTR_ISO_SDU_DATA_START_OFFSET; /* Start at the data buffer, save space for Dataload. */ + pSduBuf = pIsoalRxCtx->pPendSduBuf + pIsoalRxCtx->rxSduOffset; + + switch (segHdr.sc) + { + case HCI_ISOAL_SEG_HDR_SC_START: + pIsoalRxCtx->data.framed.timeOffset = segHdr.toffs; + break; + + case HCI_ISOAL_SEG_HDR_SC_CONT: + default: + LL_TRACE_WARN1("Missed start of segmentation; dropping packet, handle=%u", handle); + WsfMsgFree(pIsoalRxCtx->pPendSduBuf); + pIsoalRxCtx->pPendSduBuf = NULL; + pDataBuf += segHdr.len; + remLen -= hdrLen + segHdr.len; + continue; + } + break; + } + + case LL_ISO_SDU_STATE_CONT: + { + pSduBuf = pIsoalRxCtx->pPendSduBuf + pIsoalRxCtx->rxSduOffset; + + switch (segHdr.sc) + { + case HCI_ISOAL_SEG_HDR_SC_CONT: + break; + + case HCI_ISOAL_SEG_HDR_SC_START: + default: + LL_TRACE_WARN1("Expected continuation bit but got start bit; dropping packet, handle=%u", handle); + WsfMsgFree(pIsoalRxCtx->pPendSduBuf); + pIsoalRxCtx->pPendSduBuf = NULL; + pDataBuf += segHdr.len; + remLen -= hdrLen + segHdr.len; + pIsoalRxCtx->rxState = LL_ISO_SDU_STATE_NEW; + continue; + } + break; + } + + default: + LL_TRACE_WARN2("Unknown ISOAL state, handle=%u state=%u", handle, pIsoalRxCtx->rxState); + if (pIsoalRxCtx->pPendSduBuf) + { + WsfMsgFree(pIsoalRxCtx->pPendSduBuf); + pIsoalRxCtx->pPendSduBuf = NULL; + } + pDataBuf += segHdr.len; + remLen -= hdrLen + segHdr.len; + continue; + } + + memcpy(pSduBuf, pDataBuf, segHdr.len); + pDataBuf += segHdr.len; + pIsoalRxCtx->rxSduOffset += segHdr.len; + + /* SDU Complete, queue up SDU to host. */ + if (segHdr.cmplt) + { + lctrIsoHdr_t isoHdr = { 0 }; + isoHdr.handle = handle; + isoHdr.len = pIsoalRxCtx->rxSduOffset - (HCI_ISO_HDR_LEN + HCI_ISO_DL_MAX_LEN); + isoHdr.pktSn = pIsoalRxCtx->packetSequence++; + isoHdr.sduLen = isoHdr.len; + isoHdr.tsFlag = 1; + isoHdr.pb = LCTR_PB_COMP; + /* isoHdr.ps = LCTR_PS_VALID; */ /* Already done. */ + isoHdr.ts = pIsoalRxCtx->data.framed.timeOffset; /* TODO: Fill out timestamp based on anchor point */ + + uint8_t *pIsoHdrBuf = (pIsoalRxCtx->pPendSduBuf); + lctrIsoPackHdr(pIsoHdrBuf, &isoHdr); + + /* Queue SDU. */ + WsfMsgEnq(pRxQueue, handle, pIsoalRxCtx->pPendSduBuf); + /* lctrIsoDataRxDecAvailBuf(); */ /* Handled in lctrRxSduAlloc. */ + totalSduQueued++; + + pIsoalRxCtx->pPendSduBuf = NULL; + remLen -= hdrLen + segHdr.len; + pIsoalRxCtx->rxState = LL_ISO_SDU_STATE_NEW; + } + /* SDU Incomplete, save offset and return. */ + else + { + pIsoalRxCtx->rxState = LL_ISO_SDU_STATE_CONT; + return totalSduQueued; + } + } + + return totalSduQueued; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_master_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_master_phy.c index 6df99ca0429..34c2896a18b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_master_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_master_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller PHY features (master) implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller PHY features (master) implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for PHY features (master). - * - * \return None. */ /*************************************************************************************************/ void LctrMstPhyConnInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_past.c index 47eb3991863..c130ea5ac35 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller periodic sync transfer implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller periodic sync transfer implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -203,8 +204,6 @@ uint8_t LctrSetPeriodicAdvSyncTransParams(uint16_t connHandle, uint8_t mode, uin /*! * \brief Initialize lctr subsystem for PAST(Periodic advertising sync transfer). * - * \return None. - * * This function initializes the lctr subsystem for PAST(Periodic advertising sync transfer). */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_pc.c new file mode 100644 index 00000000000..9d1514134a2 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_pc.c @@ -0,0 +1,320 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller power control implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_conn.h" +#include "lmgr_api_conn.h" +#include "ll_api.h" +#include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include +#include "lctr_api_pc.h" +#include "lctr_int_pc.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize power control resources. + */ +/*************************************************************************************************/ +void LctrPowerControlInit(void) +{ + /* Initialize power control. */ + lmgrPersistCb.featuresDefault |= (LL_FEAT_POWER_CHANGE_IND | LL_FEAT_POWER_CONTROL_REQUEST); + lctrPcActTbl[LCTR_PC_MONITOR_AUTO] = lctrAutoPowerMonitorAct; + + /* Initialize path loss. */ + lmgrPersistCb.featuresDefault |= (LL_FEAT_PATH_LOSS_MONITOR); + lctrPcActTbl[LCTR_PC_MONITOR_PATH_LOSS] = lctrPathLossMonitorAct; + + /* Initialize state machines. */ + lctrSlvLlcpSmTbl[LCTR_LLCP_SM_PC] = lctrLlcpExecutePclSm; + lctrMstLlcpSmTbl[LCTR_LLCP_SM_PC] = lctrLlcpExecutePclSm; + + /* Initialize function pointers. */ + lctrSendPowerChangeIndCback = lctrSendPowerChangeInd; + lctrNotifyPowerReportIndCback = lctrNotifyPowerReportInd; +} + +/*************************************************************************************************/ +/*! + * \brief Calculate path loss of a connection context. + * + * \param pCtx Connection context. + * + * \return Current path loss + */ +/*************************************************************************************************/ +static uint8_t lctrCalcPathLoss(lctrConnCtx_t *pCtx) +{ + int8_t txPower = pCtx->peerTxPower; + int8_t lastRssi = pCtx->rssi; + + return (uint8_t) (WSF_MAX(txPower, lastRssi) - WSF_MIN(txPower, lastRssi)); +} + +/*************************************************************************************************/ +/*! + * \brief Calculate the path loss zone of a connection context. + * + * \param pCtx Connection context. + * + * \return Path loss zone. + */ +/*************************************************************************************************/ +uint8_t lctrCalcPathLossZone(lctrConnCtx_t *pCtx) +{ + uint8_t pathLoss = lctrCalcPathLoss(pCtx); + uint8_t curZone = pCtx->pclMonitorParam.pathLoss.curZone; + + uint8_t highUpperBound = pCtx->pclMonitorParam.pathLoss.highThreshold + pCtx->pclMonitorParam.pathLoss.highHysteresis; + uint8_t highLowerBound = pCtx->pclMonitorParam.pathLoss.highThreshold - pCtx->pclMonitorParam.pathLoss.highHysteresis; + + uint8_t lowUpperBound = pCtx->pclMonitorParam.pathLoss.lowThreshold + pCtx->pclMonitorParam.pathLoss.lowHysteresis; + uint8_t lowLowerBound = pCtx->pclMonitorParam.pathLoss.lowThreshold - pCtx->pclMonitorParam.pathLoss.lowHysteresis; + + switch (curZone) + { + case LL_PATH_LOSS_ZONE_LOW: + { + if (pathLoss > highUpperBound) + { + return LL_PATH_LOSS_ZONE_HIGH; + } + else if (pathLoss > lowUpperBound) + { + return LL_PATH_LOSS_ZONE_MID; + } + else + { + return LL_PATH_LOSS_ZONE_LOW; + } + } + + case LL_PATH_LOSS_ZONE_MID: + { + if (pathLoss > highUpperBound) + { + return LL_PATH_LOSS_ZONE_HIGH; + } + else if (pathLoss < lowLowerBound) + { + return LL_PATH_LOSS_ZONE_LOW; + } + else + { + return LL_PATH_LOSS_ZONE_MID; + } + } + + case LL_PATH_LOSS_ZONE_HIGH: + { + if (pathLoss < lowLowerBound) + { + return LL_PATH_LOSS_ZONE_LOW; + } + else if (pathLoss < highLowerBound) + { + return LL_PATH_LOSS_ZONE_MID; + } + else + { + return LL_PATH_LOSS_ZONE_HIGH; + } + } + + default: + LL_TRACE_ERR1("lctrCalcPathLossZone: Path loss invalid zone: %d", curZone); + return LL_PATH_LOSS_ZONE_MID; + } +} + +/*************************************************************************************************/ +/*! + * \brief Set path loss reporting parameters + * + * \param handle Connection handle. + * \param highThresh High threshold. + * \param highHyst High hysteresis. + * \param lowThresh Low threshold. + * \param lowHyst Low hysteresis. + * \param minTime Minimum time spent to trigger event. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrSetPathLossReportingParams(uint16_t handle, uint8_t highThresh, uint8_t highHyst, uint8_t lowThresh, uint8_t lowHyst, uint16_t minTime) +{ + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(handle); + + memset(&pCtx->pclMonitorParam.pathLoss, 0, sizeof(pCtx->pclMonitorParam.pathLoss)); + pCtx->pclMonitorParam.pathLoss.highThreshold = highThresh; + pCtx->pclMonitorParam.pathLoss.highHysteresis = highHyst; + pCtx->pclMonitorParam.pathLoss.lowThreshold = lowThresh; + pCtx->pclMonitorParam.pathLoss.lowHysteresis = lowHyst; + pCtx->pclMonitorParam.pathLoss.minTimeSpent = minTime; + pCtx->pclMonitorParam.pathLoss.curZone = LL_PATH_LOSS_ZONE_MID; + + if ((pCtx->powerMonitorScheme == LCTR_PC_MONITOR_PATH_LOSS) && + (pCtx->monitoringState = LCTR_PC_MONITOR_ENABLED)) + { + pCtx->pclMonitorParam.pathLoss.curZone = lctrCalcPathLossZone(pCtx); + lctrNotifyHostPathLossRpt(pCtx); + } + else + { + pCtx->powerMonitorScheme = LCTR_PC_MONITOR_PATH_LOSS; + pCtx->monitoringState = LCTR_PC_MONITOR_READY; + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Set path loss enable. + * + * \param handle Connection handle. + * \param enable Enable. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t lctrSetPathLossReportingEnable(uint16_t handle, uint8_t enable) +{ + lctrConnCtx_t *pCtx = LCTR_GET_CONN_CTX(handle); + if (pCtx->monitoringState != LCTR_PC_MONITOR_READY) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + + /* If peer Tx power is unavailable, read the peer tx power. */ + if (pCtx->peerTxPower == LL_PWR_CTRL_TXPOWER_UNAVAILABLE) + { + pCtx->pclMonitorParam.pathLoss.initialPathLossRead = TRUE; + pCtx->controllerInitRead = TRUE; + uint8_t reqPhy = pCtx->bleData.chan.rxPhy + (((pCtx->bleData.chan.rxPhy == BB_PHY_BLE_CODED) && (pCtx->bleData.chan.initTxPhyOptions == BB_PHY_OPTIONS_BLE_S2)) ? 1 : 0); + + lctrMsgPwrCtrlReq_t *pMsg; + if ((pMsg = (lctrMsgPwrCtrlReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = LCTR_GET_CONN_HANDLE(pCtx); + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_PWR_CTRL_REQ; + pMsg->delta = 0; + pMsg->phy = reqPhy; + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + else + { + LL_TRACE_WARN0("lctrSetPathLossReportingEnable: Failed to alloc power control read request."); + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + } + else + { + pCtx->pclMonitorParam.pathLoss.curZone = lctrCalcPathLossZone(pCtx); + lctrNotifyHostPathLossRpt(pCtx); + } + + pCtx->monitoringState = LCTR_PC_MONITOR_ENABLED; + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Notify the host of a path loss zone change event. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrNotifyHostPathLossRpt(lctrConnCtx_t *pCtx) +{ + const uint16_t handle = LCTR_GET_CONN_HANDLE(pCtx); + uint8_t curPathLoss = lctrCalcPathLoss(pCtx); + + LlPathLossThresholdEvt_t evt = + { + .hdr = + { + .param = handle, + .event = LL_PATH_LOSS_REPORTING_IND, + .status = LL_SUCCESS + }, + + .connHandle = handle, + .curPathLoss = curPathLoss, + .zoneEntered = pCtx->pclMonitorParam.pathLoss.curZone, + }; + + LL_TRACE_INFO3("### LlEvent ### lctrNotifyHostPathLossRpt , handle=%u, zoneEntered=%d, curPathLoss=%d", handle, pCtx->pclMonitorParam.pathLoss.curZone, curPathLoss); + + LmgrSendEvent((LlEvt_t *)&evt); +} + +/*************************************************************************************************/ +/*! + * \brief Path loss monitoring action. + * + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +void lctrPathLossMonitorAct(lctrConnCtx_t *pCtx) +{ + /* If the first path loss zone has not been generated yet, skip monitoring. */ + if (pCtx->pclMonitorParam.pathLoss.initialPathLossRead == TRUE) + { + return; + } + + uint8_t newZone = lctrCalcPathLossZone(pCtx); + uint8_t curZone = pCtx->pclMonitorParam.pathLoss.curZone; + + if (newZone == curZone) + { + pCtx->pclMonitorParam.pathLoss.curTimeSpent = 0; + pCtx->pclMonitorParam.pathLoss.newZone = newZone; + return; + } + else if (newZone != pCtx->pclMonitorParam.pathLoss.newZone) + { + pCtx->pclMonitorParam.pathLoss.curTimeSpent = 0; + pCtx->pclMonitorParam.pathLoss.newZone = newZone; + return; + } + + /* Implies that the newZone is a consecutive event. */ + pCtx->pclMonitorParam.pathLoss.curTimeSpent++; + + if (pCtx->pclMonitorParam.pathLoss.curTimeSpent >= + pCtx->pclMonitorParam.pathLoss.minTimeSpent) + { + LL_TRACE_INFO2("lctrPathLossMonitorAct, New zone entered. newZone=%u, pathLoss=%u", newZone, lctrCalcPathLoss(pCtx)); + pCtx->pclMonitorParam.pathLoss.curTimeSpent = 0; + pCtx->pclMonitorParam.pathLoss.curZone = newZone; + + lctrNotifyHostPathLossRpt(pCtx); + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_priv.c index 281f7319adb..3d139e14a5c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller privacy implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller privacy implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -44,8 +45,6 @@ lctrPrivCtx_t lctrPriv; /*************************************************************************************************/ /*! * \brief Restart resolvable private address timer. - * - * \return None. */ /*************************************************************************************************/ static void lctrRestartResPrivAddrTimer(void) @@ -59,8 +58,6 @@ static void lctrRestartResPrivAddrTimer(void) * \brief Privacy message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void lctrPrivDisp(LctrPrivMsg_t *pMsg) @@ -107,8 +104,6 @@ static void lctrPrivDisp(LctrPrivMsg_t *pMsg) * \param peer TRUE if this is a peer RPA. * \param peerAddrType Peer identity address type. * \param peerIdentityAddr Peer identity address. - * - * \return None. */ /*************************************************************************************************/ static void lctrPrivPendAddrRes(uint64_t rpa, bool_t peer, uint8_t peerAddrType, uint64_t peerIdentityAddr) @@ -152,8 +147,6 @@ static void lctrPrivPendAddrRes(uint64_t rpa, bool_t peer, uint8_t peerAddrType, * \brief Set resolvable private address timeout. * * \param timeout Timeout in seconds. - * - * \return None. */ /*************************************************************************************************/ void LctrPrivSetResPrivAddrTimeout(uint32_t timeout) @@ -165,8 +158,6 @@ void LctrPrivSetResPrivAddrTimeout(uint32_t timeout) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for privacy. - * - * \return None. */ /*************************************************************************************************/ void LctrPrivInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_sc.c index 7138c7a4e83..7a0f18aa04c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller secure connections implementation file. + * \file + * + * \brief Link layer controller secure connections implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -38,8 +39,6 @@ * \brief Baseband driver ECC service function. * * \param op Operation to service. - * - * \return None. */ /*************************************************************************************************/ static void lctrScBbDrvEcc(uint8_t op) @@ -84,8 +83,6 @@ static int lctrRng(uint8_t *pDest, unsigned size) * \param pDest Destination buffer. * \param pSrc Source buffer. * \param len Length of data, in octets. - * - * \return None. */ /*************************************************************************************************/ static void lctrReverseCopy(uint8_t *pDest, const uint8_t *pSrc, uint16_t len) @@ -103,8 +100,6 @@ static void lctrReverseCopy(uint8_t *pDest, const uint8_t *pSrc, uint16_t len) * * \param p Buffer. * \param len Length of data, in octets. - * - * \return None. */ /*************************************************************************************************/ static void lctrReverse(uint8_t *p, uint16_t len) @@ -125,8 +120,6 @@ static void lctrReverse(uint8_t *p, uint16_t len) /*************************************************************************************************/ /*! * \brief Start generating P-256 key pair. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateP256KeyPairStart(void) @@ -148,8 +141,6 @@ void lctrGenerateP256KeyPairStart(void) * \brief Start generating P-256 public key with a specified private key. * * \param pPrivKey Private key. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateP256PublicKeyStart(const uint8_t *pPrivKey) @@ -190,8 +181,6 @@ bool_t lctrGenerateP256KeyPairContinue(void) * * \param pPubKey Storage for public key. * \param pPrivKey Storage for private key. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateP256KeyPairComplete(uint8_t *pPubKey, uint8_t *pPrivKey) @@ -211,8 +200,6 @@ void lctrGenerateP256KeyPairComplete(uint8_t *pPubKey, uint8_t *pPrivKey) * * \param pPubKey Public key. * \param pPrivKey Private key. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateDhKeyStart(const uint8_t *pPubKey, const uint8_t *pPrivKey) @@ -255,8 +242,6 @@ bool_t lctrGenerateDhKeyContinue(void) * \brief Get results from generating Diffie-Hellman key. * * \param pDhKey Storage for Diffie-Hellman key. - * - * \return None. */ /*************************************************************************************************/ void lctrGenerateDhKeyComplete(uint8_t *pDhKey) @@ -302,8 +287,6 @@ bool_t lctrValidatePublicKey(const uint8_t *pPubKey, bool_t generateKey) * \brief Notify host of key generation. * * \param pPubKey Public key. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyReadLocalP256PubKeyInd(const uint8_t *pPubKey) @@ -332,8 +315,6 @@ static void lctrNotifyReadLocalP256PubKeyInd(const uint8_t *pPubKey) * \brief Notify host of key generation. * * \param pDhKey Diffie-Hellman key. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyGenerateDhKeyInd(const uint8_t *pDhKey) @@ -359,8 +340,6 @@ static void lctrNotifyGenerateDhKeyInd(const uint8_t *pDhKey) /*************************************************************************************************/ /*! * \brief P-256 key pair generation. - * - * \return None. */ /*************************************************************************************************/ static void lctrScGenerateP256KeyPairContinue(void) @@ -382,8 +361,6 @@ static void lctrScGenerateP256KeyPairContinue(void) /*************************************************************************************************/ /*! * \brief DH Key generation. - * - * \return None. */ /*************************************************************************************************/ static void lctrScGenerateDhKeyContinue(void) @@ -548,8 +525,6 @@ uint8_t LctrSetValidatePublicKeyMode(uint8_t validateMode) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for secure connections. - * - * \return None. */ /*************************************************************************************************/ void LctrScInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_slave_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_slave_phy.c index 3edbe1a4542..fcb64785de3 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_slave_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_main_slave_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller PHY features (slave) implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller PHY features (slave) implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for PHY features (slave). - * - * \return None. */ /*************************************************************************************************/ void LctrSlvPhyConnInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv.h index 4bbdf99bf70..286440d2d98 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller advertising channel packet interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2017 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller advertising channel packet interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_ae.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_ae.h index bc7e23d05ce..08acdd013ce 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_ae.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_ae.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller extended advertising channel packet interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller extended advertising channel packet interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -104,6 +105,9 @@ typedef struct uint16_t eventCounter; /*!< Event counter. */ } lctrSyncInfo_t; +/*! \brief Pack ACAD call signature. */ +typedef uint8_t (*lctrPackAcad_t)(lctrAdvSet_t *, uint8_t *); + /************************************************************************************************** Function Declarations **************************************************************************************************/ @@ -118,12 +122,15 @@ void lctrPackAuxPtr(lctrAdvSet_t const *pAdvSet, uint32_t offsUsec, uint8_t chId uint8_t lctrPackLegacyAdvPdu(lctrAdvSet_t *pAdvSet, uint8_t *pPduBuf); uint8_t lctrPackLegacyScanRspPdu(lctrAdvSet_t *pAdvSet, uint8_t *pPduBuf); uint8_t lctrPackSyncIndPdu(lctrAdvSet_t *pAdvSet, uint8_t *pPduBuf, lctrAdvDataBuf_t *pAdvData, bool_t isPeriodic); -uint8_t* lctrPackAcad(lctrAdvSet_t *pAdvSet, uint8_t commExtAdvPdu, uint8_t *pBuf, uint16_t *pRemLen, uint8_t acadId); +uint8_t lctrPackAcadChanMapUpd(lctrAdvSet_t *pAdvSet, uint8_t *pBuf); +uint8_t lctrPackAcadBigInfo(lctrAdvSet_t *pAdvSet, uint8_t *pBuf); /* Unpack */ uint8_t lctrUnpackExtAdvHeader(lctrExtAdvHdr_t *pPdu, uint8_t *pNewFlags, const uint8_t *pBuf); void lctrUnpackAuxPtr(lctrAuxPtr_t *pAuxPtr, const uint8_t *pBuf); void lctrUnpackSyncInfo(lctrSyncInfo_t *pSyncInfo, const uint8_t *pBuf); +void lctrUnpackAcadChanMapUpd(LctrAcadChanMapUpd_t *pChanMapUpd, const uint8_t *pBuf); +void lctrUnpackAcadBigInfo(LctrAcadBigInfo_t *pBigInfo, const uint8_t *pBuf, uint8_t len); #ifdef __cplusplus }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_master_ae.c index 9b87a223b4a..a076cfa07da 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave extended advertising operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave extended advertising operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -99,19 +100,20 @@ uint8_t lctrUnpackExtAdvHeader(lctrExtAdvHdr_t *pPdu, uint8_t *pNewFlags, const { BSTREAM_TO_UINT8(pPdu->txPwr, pBuf); } + } - if ((pPdu->extHdrLen + 1) > (pBuf - pStartBuf)) - { - pPdu->pAcad = pBuf; - pPdu->acadLen = (pPdu->extHdrLen + 1) - (pBuf - pStartBuf); - pBuf += pPdu->acadLen; - } - else - { - pPdu->pAcad = NULL; - pPdu->acadLen = 0; - } + if ((pPdu->extHdrLen + 1) > (pBuf - pStartBuf)) + { + pPdu->pAcad = pBuf; + pPdu->acadLen = (pPdu->extHdrLen + 1) - (pBuf - pStartBuf); + pBuf += pPdu->acadLen; } + else + { + pPdu->pAcad = NULL; + pPdu->acadLen = 0; + } + return pBuf - pStartBuf; } @@ -121,8 +123,6 @@ uint8_t lctrUnpackExtAdvHeader(lctrExtAdvHdr_t *pPdu, uint8_t *pNewFlags, const * * \param pAuxPtr Unpacked AuxPtr data. * \param pBuf Packed AuxPtr data. - * - * \return None. */ /*************************************************************************************************/ void lctrUnpackAuxPtr(lctrAuxPtr_t *pAuxPtr, const uint8_t *pBuf) @@ -144,8 +144,6 @@ void lctrUnpackAuxPtr(lctrAuxPtr_t *pAuxPtr, const uint8_t *pBuf) * * \param pSyncInfo Sync info. * \param pBuf Buffer pointer to SyncInfo field. - * - * \return None. */ /*************************************************************************************************/ void lctrUnpackSyncInfo(lctrSyncInfo_t *pSyncInfo, const uint8_t *pBuf) @@ -155,7 +153,7 @@ void lctrUnpackSyncInfo(lctrSyncInfo_t *pSyncInfo, const uint8_t *pBuf) pSyncInfo->syncOffset = (field16 >> 0) & 0x1FFF; pSyncInfo->offsetUnits = (field16 >> 13) & 0x1; pSyncInfo->offsetAdjust = (field16 >> 14) & 0x1; - pBuf += 2; + pBuf += sizeof(uint16_t); BSTREAM_TO_UINT16(pSyncInfo->syncInter, pBuf); @@ -163,7 +161,7 @@ void lctrUnpackSyncInfo(lctrSyncInfo_t *pSyncInfo, const uint8_t *pBuf) BYTES_TO_UINT40(field64, pBuf); pSyncInfo->chanMap = (field64 >> 0) & LL_CHAN_DATA_ALL; pSyncInfo->sca = (field64 >> 37) & 0x07; - pBuf+=5; + pBuf += 5; BSTREAM_TO_UINT32(pSyncInfo->accAddr, pBuf); @@ -171,3 +169,76 @@ void lctrUnpackSyncInfo(lctrSyncInfo_t *pSyncInfo, const uint8_t *pBuf) BSTREAM_TO_UINT16(pSyncInfo->eventCounter, pBuf); } + +/*************************************************************************************************/ +/*! + * \brief Unpack Channel Map Update Indication. + * + * \param pChanMapUpd Unpacked Channel Map Update return buffer. + * \param pBuf Packed buffer pointer. + */ +/*************************************************************************************************/ +void lctrUnpackAcadChanMapUpd(LctrAcadChanMapUpd_t *pChanMapUpd, const uint8_t *pBuf) +{ + BSTREAM_TO_UINT40(pChanMapUpd->chanMask, pBuf); + BSTREAM_TO_UINT16(pChanMapUpd->instant, pBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Unpack BIG Info. + * + * \param pBigInfo Unpacked BIG Info return buffer. + * \param pBuf Packed buffer pointer. + * \param len length of bigInfo. + */ +/*************************************************************************************************/ +void lctrUnpackAcadBigInfo(LctrAcadBigInfo_t *pBigInfo, const uint8_t *pBuf, uint8_t len) +{ + uint32_t field32; + uint64_t field64; + + BSTREAM_TO_UINT32(field32, pBuf); + pBigInfo->bigOffs = (field32 >> 0) & 0x3FFF; + pBigInfo->bigOffsUnits = (field32 >> 14) & 0x0001; + pBigInfo->isoInter = (field32 >> 15) & 0x0FFF; + pBigInfo->numBis = (field32 >> 27) & 0x001F; + BSTREAM_TO_UINT32(field32, pBuf); + pBigInfo->nse = (field32 >> 0) & 0x0001F; + pBigInfo->bn = (field32 >> 5) & 0x00007; + pBigInfo->subEvtInterUsec = (field32 >> 8) & 0xFFFFF; + pBigInfo->pto = (field32 >> 28) & 0x0000F; + BSTREAM_TO_UINT32(field32, pBuf); + pBigInfo->bisSpaceUsec = (field32 >> 0) & 0xFFFFF; + pBigInfo->irc = (field32 >> 20) & 0x0000F; + pBigInfo->maxPdu = (field32 >> 24) & 0x000FF; + pBuf++; /* RFU */ + BSTREAM_TO_UINT32(pBigInfo->seedAccAddr, pBuf); + BSTREAM_TO_UINT32(field32, pBuf); + pBigInfo->sduInterUsec = (field32 >> 0) & 0xFFFFF; + pBigInfo->maxSdu = (field32 >> 20) & 0x00FFF; + BSTREAM_TO_UINT16(pBigInfo->baseCrcInit, pBuf); + BSTREAM_TO_UINT40(field64, pBuf); + pBigInfo->chanMap = (field64 >> 0) & UINT64_C(0x1FFFFFFFFF); + pBigInfo->phy = (field64 >> 37) & 0x0007; + BSTREAM_TO_UINT40(field64, pBuf); + pBigInfo->bisPldCtr = (field64 >> 0) & UINT64_C(0x7FFFFFFFFF); + pBigInfo->framing = (field64 >> 39) & 0x0001; + + /* Convert BIG Info enumeration to PHY value. */ + pBigInfo->phy += 1; + + if (len > (LL_ACAD_BIG_INFO_UNENCRPT_LEN + LL_ACAD_LEN_FIELD_LEN)) + { + pBigInfo->encrypt = TRUE; + + memcpy(pBigInfo->giv, pBuf, LL_GIV_LEN); + pBuf += LL_GIV_LEN; + memcpy(pBigInfo->gskd, pBuf, LL_GSKD_LEN); + /* pBuf += LL_GSKD_LEN; */ + } + else + { + pBigInfo->encrypt = FALSE; + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave.c index 45d532aacf0..f3067edaec6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising channel packet implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising channel packet implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,7 +26,6 @@ #include "util/bstream.h" #include "wsf_trace.h" #include -#include /*************************************************************************************************/ /*! diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave_ae.c index d0bef7b1cdb..a93a841c7ff 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave extended advertising operation builder implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave extended advertising operation builder implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -39,14 +40,23 @@ /*! \brief Assert minimum advertising payload length can contain a legacy length payload. */ WSF_CT_ASSERT(BB_ADV_PLD_MAX_LEN > (LL_EXT_ADV_HDR_MAX_LEN + LL_ADVBU_MAX_LEN)); +/************************************************************************************************** + Local Variables +**************************************************************************************************/ + +/*! \brief Packing lookup table; local use only. */ +static const lctrPackAcad_t lctrPackAcad[LCTR_ACAD_NUM_ID] = +{ + lctrPackAcadChanMapUpd, /*!< Channel map update. */ + lctrPackAcadBigInfo /*!< BIG Info. */ +}; + /*************************************************************************************************/ /*! * \brief Pack Sync info field. * * \param pAdvSet Advertising set. * \param pSyncInfo Packed SyncInfo field. - * - * \return None. */ /*************************************************************************************************/ static void lctrPackSyncInfo(lctrAdvSet_t *pAdvSet, uint8_t *pSyncInfo) @@ -59,18 +69,18 @@ static void lctrPackSyncInfo(lctrAdvSet_t *pAdvSet, uint8_t *pSyncInfo) BbOpDesc_t *pPerOp = &pAdvSet->perParam.perAdvBod; BbBleData_t *pBle = &pAdvSet->perParam.perBleData; - tempDue = pPerOp->due; + tempDue = pPerOp->dueUsec; while (TRUE) { /* If sync PDU is due in the future and at least MAFS apart, update offset. */ - if ((tempDue > pAuxOp->due) && ((BB_TICKS_TO_US(tempDue - pAuxOp->due)) > LL_BLE_MAFS_US)) + if (BbGetTargetTimeDelta(tempDue, pAuxOp->dueUsec) > LL_BLE_MAFS_US) { - offsUsec = BB_TICKS_TO_US(tempDue - pAuxOp->due); + offsUsec = BbGetTargetTimeDelta(tempDue, pAuxOp->dueUsec); break; } - tempDue += pAdvSet->perParam.perAdvInter; + tempDue += pAdvSet->perParam.perAdvInterUsec; } if (offsUsec < LL_30_USEC_OFFS_MAX_USEC) @@ -94,7 +104,7 @@ static void lctrPackSyncInfo(lctrAdvSet_t *pAdvSet, uint8_t *pSyncInfo) (offsUnits << 13) | /* Offset units. */ (offsAdjust << 14)); /* Offset adjust. */ UINT16_TO_BUF(&pSyncInfo[2], /* Interval. */ - LCTR_PER_INTER_TO_MS(BB_TICKS_TO_US(pAdvSet->perParam.perAdvInter))); + LCTR_PER_INTER_TO_MS(pAdvSet->perParam.perAdvInterUsec)); uint64_t temp = ((pAdvSet->perParam.perChanParam.chanMask & LL_CHAN_DATA_ALL) |/* Channel Map. */ ((uint64_t)lctrComputeSca() << 37)); /* SCA. */ @@ -118,7 +128,7 @@ static void lctrPackSyncInfo(lctrAdvSet_t *pAdvSet, uint8_t *pSyncInfo) * \param commExtAdvPdu Common extended advertising PDU type. * \param isPeriodic This header is part of periodic PDUs or not. * - * \return PDU header buffer length. + * \return Combined Adv and ExtAdv headers length. */ /*************************************************************************************************/ static uint8_t lctrPackExtAdvHeader(lctrAdvSet_t *pAdvSet, uint8_t manExtHdrFlags, uint8_t optExtHdrFlags, @@ -129,16 +139,8 @@ static uint8_t lctrPackExtAdvHeader(lctrAdvSet_t *pAdvSet, uint8_t manExtHdrFlag pPduHdr->len = 0; uint8_t *pAuxPtr = NULL; - uint8_t *pBuf = pPduBuf + LL_ADV_HDR_LEN + LCTR_EXT_HDR_CMN_LEN + LCTR_EXT_HDR_FLAG_LEN; - - /* Check if we need to look for Acads to pack later. */ - /* Future Acad may include PDUS: - * AUX_ADV_IND, AUX_SYNC_IND, AUX_SCAN_RSP */ - bool_t acadNeeded = FALSE; - if (commExtAdvPdu == LCTR_PDU_AUX_SYNC_IND) - { - acadNeeded = TRUE; - } + uint8_t *pExtHdrBuf = pPduBuf + LL_ADV_HDR_LEN + LCTR_EXT_HDR_CMN_LEN; + uint8_t *pBuf = pExtHdrBuf + LCTR_EXT_HDR_FLAG_LEN; /* Determine the superior PDU. */ if (commExtAdvPdu == LCTR_PDU_AUX_CHAIN_IND) @@ -271,45 +273,61 @@ static uint8_t lctrPackExtAdvHeader(lctrAdvSet_t *pAdvSet, uint8_t manExtHdrFlag UINT8_TO_BSTREAM(pBuf, (uint8_t)actTxPwr); } - /* Pack Acad. */ - if (acadNeeded) + /* ACAD assembly. */ + bool_t acadPresent = FALSE; + if (commExtAdvPdu == LCTR_PDU_AUX_SYNC_IND) { - for (uint8_t acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) + for (unsigned int acadId = 0; acadId < LCTR_ACAD_NUM_ID; acadId++) { - if (pAdvSet->acadParams[acadId].hdr.state != LCTR_ACAD_STATE_DISABLED) + if (pAdvSet->acadParams[acadId].hdr.state == LCTR_ACAD_STATE_ENABLED) { - pBuf = lctrPackAcad(pAdvSet, commExtAdvPdu, pBuf, &remDataLen, acadId); + uint8_t acadLen = LL_ACAD_OPCODE_LEN + LL_ACAD_LEN_FIELD_LEN + + pAdvSet->acadParams[acadId].hdr.len; + + uint8_t availExtHdrLen = LL_EXT_ADV_HDR_MAX_LEN - (pBuf - pExtHdrBuf); + + /* Only add ACAD if space available. */ + if (acadLen <= availExtHdrLen) + { + acadPresent = TRUE; + + /* Pack ACAD immediately after the Extended Header. */ + pBuf += lctrPackAcad[acadId](pAdvSet, pBuf); + } } } } + if (!extHdrFlags && !acadPresent) + { + /* Recover optional ExtHdrFlag field since it is not used. */ + pBuf = pExtHdrBuf; + } + + /* Assign AdvData to this PDU, defer buffer assembly to DMA gather. */ uint8_t advDataLen = 0; if (remDataLen) { const unsigned int maxAvailDataLen = LL_EXT_ADVB_MAX_LEN - (pBuf - pPduBuf); availDataLen = WSF_MIN(maxAvailDataLen, availDataLen); /* Limit to maximum packet size. */ advDataLen = WSF_MIN(remDataLen, availDataLen); /* Reduce to remaining data. */ - pDataBuf->txOffs += advDataLen; - } - if (extHdrFlags == 0) - { - /* Extended Header Flags only present if bits set. */ - pBuf = pPduBuf + LL_ADV_HDR_LEN + LCTR_EXT_HDR_CMN_LEN; + /* Commit AdvData fragment to this PDU. */ + pDataBuf->txOffs += advDataLen; } /* Pack Advertising Header now that Extended Advertising Header length is known. */ - uint16_t extHdrLen = pBuf - pPduBuf - LL_ADV_HDR_LEN - LCTR_EXT_HDR_CMN_LEN; - pPduHdr->len = pBuf - pPduBuf - LL_ADV_HDR_LEN + advDataLen; + uint16_t extHdrLen = pBuf - pExtHdrBuf; + pPduHdr->len = LCTR_EXT_HDR_CMN_LEN + extHdrLen + advDataLen; lctrPackAdvbPduHdr(pPduBuf, pPduHdr); - /* Pack Extended Advertising header. */ + /* Pack Extended Advertising header; unconditionally write even if unused. */ pPduBuf[LL_ADV_HDR_LEN + 0] = extHdrLen | /* Extended Header Length */ (advMode << 6); /* AdvMode */ pPduBuf[LL_ADV_HDR_LEN + 1] = extHdrFlags; /* Extended Header Flags */ - switch(commExtAdvPdu) + switch (commExtAdvPdu) { case LCTR_PDU_ADV_EXT_IND: pAdvSet->auxOffsUsec = 0; @@ -707,8 +725,6 @@ uint8_t lctrPackAuxConnRspPdu(lctrAdvSet_t *pAdvSet, uint8_t *pPduBuf, bool_t is * \param offsUsec Auxiliary offset in microseconds. * \param chIdx Channel index. * \param pAuxPtr Packed AuxPtr buffer. - * - * \return None. */ /*************************************************************************************************/ void lctrPackAuxPtr(lctrAdvSet_t const *pAdvSet, uint32_t offsUsec, uint8_t chIdx, uint8_t *pAuxPtr) @@ -925,44 +941,79 @@ uint8_t lctrPackSyncIndPdu(lctrAdvSet_t *pAdvSet, uint8_t *pPduBuf, lctrAdvDataB /*************************************************************************************************/ /*! - * \brief Pack acad field + * \brief Pack Channel Map Update ACAD. * * \param pAdvSet Advertising set. - * \param commExtAdvPdu Common ext adv pdu. * \param pBuf Packed data buffer. - * \param pRemLen Remaining length of ext adv header. - * \param acadId Acad Id. * - * \return Modified pBuf. + * \return Length of ACAD. */ /*************************************************************************************************/ -uint8_t* lctrPackAcad(lctrAdvSet_t *pAdvSet, uint8_t commExtAdvPdu, uint8_t *pBuf, uint16_t *pRemLen, uint8_t acadId) +uint8_t lctrPackAcadChanMapUpd(lctrAdvSet_t *pAdvSet, uint8_t *pBuf) { - switch(acadId) - { - case LCTR_ACAD_ID_CHAN_MAP_UPDATE: - { - uint8_t len = LL_ACAD_LEN_FIELD_LEN + LL_ACAD_UPDATE_CHANNEL_MAP_LEN; - - if ((commExtAdvPdu != LCTR_PDU_AUX_SYNC_IND) || - (len > *pRemLen)) - { - return pBuf; - } + const uint8_t len = LL_ACAD_LEN_FIELD_LEN + LL_ACAD_CHAN_MAP_UPD_LEN; - lctrAcadChanMapUpd_t *pData = &pAdvSet->acadParams[acadId].chanMapUpdate; + LctrAcadChanMapUpd_t *pChanMapUpd = &pAdvSet->acadParams[LCTR_ACAD_ID_CHAN_MAP_UPDATE].chanMapUpdate; - /* Pack Acad */ - *pRemLen -= len; - UINT8_TO_BSTREAM(pBuf, LL_ACAD_UPDATE_CHANNEL_MAP_LEN); - UINT8_TO_BSTREAM(pBuf, LL_ACAD_OPCODE_CHANNEL_MAP_UPDATE); + /* Pack ACAD */ + UINT8_TO_BSTREAM (pBuf, LL_ACAD_CHAN_MAP_UPD_LEN); + UINT8_TO_BSTREAM (pBuf, LL_ACAD_OPCODE_CHAN_MAP_UPD); + UINT40_TO_BSTREAM(pBuf, pChanMapUpd->chanMask); + UINT16_TO_BSTREAM(pBuf, pChanMapUpd->instant); - UINT40_TO_BSTREAM(pBuf, pData->chanMask); - UINT16_TO_BSTREAM(pBuf, pData->instant); - return pBuf; - } + return len; +} - default: - return pBuf; - } +/*************************************************************************************************/ +/*! + * \brief Pack BIG Info ACAD. + * + * \param pAdvSet Advertising set. + * \param pBuf Packed data buffer. + * + * \return Length of ACAD. + */ +/*************************************************************************************************/ +uint8_t lctrPackAcadBigInfo(lctrAdvSet_t *pAdvSet, uint8_t *pBuf) +{ + LctrAcadBigInfo_t *pBigInfo = &pAdvSet->acadParams[LCTR_ACAD_ID_BIG_INFO].bigInfo; + + const uint8_t len = LL_ACAD_LEN_FIELD_LEN + LL_ACAD_OPCODE_LEN + pBigInfo->hdr.len; + + /* Convert PHY value to BIG Info enumeration. */ + uint8_t bigPhy = pBigInfo->phy - 1; + + /* Pack ACAD */ + UINT8_TO_BSTREAM (pBuf, pBigInfo->hdr.len + LL_ACAD_LEN_FIELD_LEN); + UINT8_TO_BSTREAM (pBuf, LL_ACAD_OPCODE_BIG_INFO); + + UINT32_TO_BSTREAM(pBuf, ((pBigInfo->bigOffs & 0x3FFF) << 0) | + ((pBigInfo->bigOffsUnits & 0x0001) << 14) | + ((pBigInfo->isoInter ) << 15) | + ((pBigInfo->numBis ) << 27)); + UINT32_TO_BSTREAM(pBuf, ((pBigInfo->nse ) << 0) | + ((pBigInfo->bn ) << 5) | + ((pBigInfo->subEvtInterUsec ) << 8) | + ((pBigInfo->pto ) << 28)); + UINT32_TO_BSTREAM(pBuf, ((pBigInfo->bisSpaceUsec ) << 0) | + ((pBigInfo->irc ) << 20) | + ((pBigInfo->maxPdu ) << 24)); + UINT8_TO_BSTREAM (pBuf, ((0 /* RFU */ ) << 0)); + UINT32_TO_BSTREAM(pBuf, ((pBigInfo->seedAccAddr ) << 0)); + UINT32_TO_BSTREAM(pBuf, ((pBigInfo->sduInterUsec ) << 0) | + ((pBigInfo->maxSdu ) << 20)); + UINT16_TO_BSTREAM(pBuf, ((pBigInfo->baseCrcInit ) << 0)); + UINT40_TO_BSTREAM(pBuf, ((pBigInfo->chanMap ) << 0) | + (((uint64_t)bigPhy ) << 37)); + UINT40_TO_BSTREAM(pBuf, ((pBigInfo->bisPldCtr & UINT64_C(0x7FFFFFFFFF)) << 0) | + ((pBigInfo->framing & UINT64_C(1)) << 39)); + if (pBigInfo->encrypt) + { + memcpy(pBuf, pBigInfo->giv, LL_GIV_LEN); + pBuf += LL_GIV_LEN; + memcpy(pBuf, pBigInfo->gskd, LL_GSKD_LEN); + pBuf += LL_GSKD_LEN; + } + + return len; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_bis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_bis.c new file mode 100644 index 00000000000..404dacf6d10 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_bis.c @@ -0,0 +1,171 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller BIS packet implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_pdu_iso.h" +#include "util/bstream.h" +#include "hci_defs.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Pack a BIS Data PDU header. + * + * \param pBuf Packed packet buffer. + * \param pHdr Unpacked PDU header. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrBisPackDataPduHdr(uint8_t *pBuf, const lctrBisDataPduHdr_t *pHdr) +{ + const uint8_t len = LL_DATA_HDR_LEN; + + uint16_t hdr = 0; + + hdr |= (pHdr->llid ) << 0; + hdr |= (pHdr->cssn & 7) << 2; + hdr |= (pHdr->cstf ) << 5; + hdr |= (pHdr->len ) << 8; + UINT16_TO_BSTREAM(pBuf, hdr); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG Channel Map indication. + * + * \param pBuf Packed packet buffer. + * \param chanMap Channel map. + * \param instance Instance. + * + * \return Packet length. + */ +/*************************************************************************************************/ +uint8_t lctrBisPackBigChannelMapInd(uint8_t *pBuf, uint64_t chanMap, uint16_t instance) +{ + const uint8_t len = sizeof(uint8_t) + LL_BIG_CHAN_MAP_IND_PDU_LEN; + + UINT8_TO_BSTREAM (pBuf, LL_BIG_OPCODE_CHAN_MAP_IND); + UINT40_TO_BSTREAM(pBuf, chanMap); + UINT16_TO_BSTREAM(pBuf, instance); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG Terminate indication. + * + * \param pBuf Packed packet buffer. + * \param reason Reason code. + * \param instance Instance. + * + * \return Packet length. + */ +/*************************************************************************************************/ +uint8_t lctrBisPackBigTerminateInd(uint8_t *pBuf, uint8_t reason, uint16_t instance) +{ + const uint8_t len = sizeof(uint8_t) + LL_BIG_TERMINATE_IND_PDU_LEN; + + UINT8_TO_BSTREAM (pBuf, LL_BIG_OPCODE_BIG_TERM_IND); + UINT8_TO_BSTREAM (pBuf, reason); + UINT16_TO_BSTREAM(pBuf, instance); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a BIS Data PDU header. + * + * \param pHdr Unpacked header. + * \param pBuf Packed packet buffer. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrBisUnpackDataPduHdr(lctrBisDataPduHdr_t *pHdr, const uint8_t *pBuf) +{ + const uint8_t len = LL_DATA_HDR_LEN; + + uint16_t hdr; + + BSTREAM_TO_UINT16(hdr, pBuf); + + pHdr->llid = (hdr >> 0) & 0x03; + pHdr->cssn = (hdr >> 2) & 0x07; + pHdr->cstf = (hdr >> 5) & 0x01; + pHdr->len = (hdr >> 8); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a BIG Channel Map indication. + * + * \param pChanMap Channel map return buffer. + * \param pInstance Instance return buffer. + * \param pBuf Packed packet buffer. + * + * \return PDU length. + */ +/*************************************************************************************************/ +uint8_t lctrBisUnpackBigChannelMapInd(uint64_t *pChanMap, uint16_t *pInstance, const uint8_t *pBuf) +{ + const uint8_t len = sizeof(uint8_t) + LL_BIG_CHAN_MAP_IND_PDU_LEN; + + uint64_t chanMap; + uint16_t instance; + + pBuf++; /* Opcode */ + BSTREAM_TO_UINT40(chanMap, pBuf); + BSTREAM_TO_UINT16(instance, pBuf); + + *pChanMap = chanMap; + *pInstance = instance; + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a BIG Terminate indication. + * + * \param pReason Channel map return buffer. + * \param pInstance Instance return buffer. + * \param pBuf Packed packet buffer. + * + * \return PDU length. + */ +/*************************************************************************************************/ +uint8_t lctrBisUnpackBigTerminateInd(uint8_t *pReason, uint16_t *pInstance, const uint8_t *pBuf) +{ + const uint8_t len = sizeof(uint8_t) + LL_BIG_TERMINATE_IND_PDU_LEN; + + pBuf++; /* Opcode */ + BSTREAM_TO_UINT8 (*pReason, pBuf); + BSTREAM_TO_UINT16(*pInstance, pBuf); + + return len; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.c index 701d0963e8a..f44df7ffb0b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave data channel packet implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave data channel packet implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,7 +28,6 @@ #include "hci_defs.h" #include "wsf_math.h" #include -#include /*************************************************************************************************/ /*! @@ -639,7 +639,7 @@ uint8_t lctrUnpackCisReqPdu(lctrCisReq_t *pPdu, const uint8_t *pBuf) BSTREAM_TO_UINT8 (pPdu->phySToM, pBuf); BSTREAM_TO_UINT16 (sduSizeMToS, pBuf); - pPdu->isoalPduType = (sduSizeMToS >> 15) & 0x01; + pPdu->framing = (sduSizeMToS >> 15) & 0x01; pPdu->sduSizeMToS = sduSizeMToS & 0x0FFF; BSTREAM_TO_UINT16 (pPdu->sduSizeSToM, pBuf); pPdu->sduSizeSToM &= 0x0FFF; @@ -648,8 +648,8 @@ uint8_t lctrUnpackCisReqPdu(lctrCisReq_t *pPdu, const uint8_t *pBuf) BSTREAM_TO_UINT24 (pPdu->sduIntervalSToM, pBuf); pPdu->sduIntervalSToM &= 0xFFFFF; - BSTREAM_TO_UINT8 (pPdu->plMToS, pBuf); - BSTREAM_TO_UINT8 (pPdu->plSToM, pBuf); + BSTREAM_TO_UINT16 (pPdu->plMToS, pBuf); + BSTREAM_TO_UINT16 (pPdu->plSToM, pBuf); BSTREAM_TO_UINT8 (pPdu->nse, pBuf); BSTREAM_TO_UINT24 (pPdu->subIntervUsec, pBuf); BSTREAM_TO_UINT8 (bn, pBuf); @@ -733,6 +733,73 @@ uint8_t lctrUnpackCisTermPdu(lctrCisTermInd_t *pPdu, const uint8_t *pBuf) return len; } +/*************************************************************************************************/ +/*! + * \brief Unpack a Power indication PDU. + * + * \param pPdu Power indication PDU. + * \param pBuf Packed packet buffer. + * + * \return PDU length. + */ +/*************************************************************************************************/ +static uint8_t lctrUnpackPwrChngIndPdu(lctrPwrChngInd_t *pPdu, const uint8_t *pBuf) +{ + const uint8_t len = LL_PWR_CHNG_IND_LEN; + + pBuf += 1; /* skip opcode */ + BSTREAM_TO_UINT8 (pPdu->phy, pBuf); + BSTREAM_TO_UINT8 (pPdu->limits, pBuf); + BSTREAM_TO_UINT8 (pPdu->delta, pBuf); + BSTREAM_TO_UINT8 (pPdu->txPower, pBuf); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a power control request PDU. + * + * \param pPdu Power indication PDU. + * \param pBuf Packed packet buffer. + * + * \return PDU length. + */ +/*************************************************************************************************/ +static uint8_t lctrUnpackPwrCtrlReqPdu(lctrPwrCtrlReq_t *pPdu, const uint8_t *pBuf) +{ + const uint8_t len = LL_PWR_CTRL_REQ_LEN; + + pBuf += 1; /* skip opcode */ + BSTREAM_TO_UINT8 (pPdu->phy, pBuf); + BSTREAM_TO_UINT8 (pPdu->delta, pBuf); + BSTREAM_TO_UINT8 (pPdu->txPower, pBuf); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a power control response PDU. + * + * \param pPdu Power indication PDU. + * \param pBuf Packed packet buffer. + * + * \return PDU length. + */ +/*************************************************************************************************/ +static uint8_t lctrUnpackPwrCtrlRspPdu(lctrPwrCtrlRsp_t *pPdu, const uint8_t *pBuf) +{ + const uint8_t len = LL_PWR_CTRL_RSP_LEN; + + pBuf += 1; /* skip opcode */ + BSTREAM_TO_UINT8 (pPdu->limits, pBuf); + BSTREAM_TO_UINT8 (pPdu->delta, pBuf); + BSTREAM_TO_UINT8 (pPdu->txPower, pBuf); + BSTREAM_TO_UINT8 (pPdu->apr, pBuf); + + return len; +} /*************************************************************************************************/ /*! * \brief Decode an LE-C channel buffer. @@ -984,6 +1051,36 @@ uint8_t lctrDecodeCtrlPdu(lctrDataPdu_t *pPdu, const uint8_t *pBuf, uint8_t role return LL_ERROR_CODE_UNKNOWN_LMP_PDU; } break; + case LL_PDU_PWR_CHNG_IND: + if ((lmgrCb.features & LL_FEAT_POWER_CHANGE_IND) == 0) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + if (lctrUnpackPwrChngIndPdu(&pPdu->pld.pwrChngInd, pBuf) != pPdu->hdr.len) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + break; + case LL_PDU_PWR_CTRL_REQ: + if ((lmgrCb.features & LL_FEAT_POWER_CONTROL_REQUEST) == 0) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + if (lctrUnpackPwrCtrlReqPdu(&pPdu->pld.pwrCtrlReq, pBuf) != pPdu->hdr.len) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + break; + case LL_PDU_PWR_CTRL_RSP: + if ((lmgrCb.features & LL_FEAT_POWER_CONTROL_REQUEST) == 0) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + if (lctrUnpackPwrCtrlRspPdu(&pPdu->pld.pwrCtrlRsp, pBuf) != pPdu->hdr.len) + { + return LL_ERROR_CODE_UNKNOWN_LMP_PDU; + } + break; default: result = LL_ERROR_CODE_UNKNOWN_LMP_PDU; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.h index 904fd6a1c82..bb33c728dfe 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_conn.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller data channel packet interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller data channel packet interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -209,13 +210,13 @@ typedef struct uint8_t cisId; /*!< CIS identifier. */ uint8_t phyMToS; /*!< Master to slave PHY. */ uint8_t phySToM; /*!< Slave to Master PHY. */ - uint8_t isoalPduType; /*!< ISOAL PDU type. */ + uint8_t framing; /*!< PDU framing type. */ uint16_t sduSizeMToS; /*!< Maximum SDU size from the master Host. */ uint16_t sduSizeSToM; /*!< Maximum SDU size from the slave Host. */ uint32_t sduIntervalMToS; /*!< Time interval between the start of consecutive SDUs from the master Host */ uint32_t sduIntervalSToM; /*!< Time interval between the start of consecutive SDUs from the master Host */ - uint8_t plMToS; /*!< Master to slave payload. */ - uint8_t plSToM; /*!< Slave to master payload. */ + uint16_t plMToS; /*!< Master to slave payload. */ + uint16_t plSToM; /*!< Slave to master payload. */ uint8_t nse; /*!< Number of subevent. */ uint32_t subIntervUsec; /*!< Contain the time between the start of a subevent and the start of the next subevent, 24 significant bits. */ uint8_t bnMToS; /*!< Master to slave burst number, 4 significant bits. */ @@ -254,6 +255,32 @@ typedef struct uint8_t reason; /*!< Reason for termination. */ } lctrCisTermInd_t; +/*! \brief Power control request PDU. */ +typedef struct +{ + uint8_t phy; /*!< PHY. */ + int8_t delta; /*!< Requested delta. */ + int8_t txPower; /*!< Local transmit power. */ +} lctrPwrCtrlReq_t; + +/*! \brief Power control RSP PDU. */ +typedef struct +{ + uint8_t limits; /*!< Limits field. */ + int8_t delta; /*!< Change in power. */ + int8_t txPower; /*!< Local txPower. */ + uint8_t apr; /*!< Acceptable power reduction. */ +} lctrPwrCtrlRsp_t; + +/*! \brief Power change indication PDU. */ +typedef struct +{ + uint8_t phy; /*!< PHY. */ + uint8_t limits; /*!< Limits field. */ + int8_t delta; /*!< Device txPower change. */ + int8_t txPower; /*!< Local txPower. */ +} lctrPwrChngInd_t; + /*! \brief Data channel control PDU. */ typedef struct { @@ -284,6 +311,9 @@ typedef struct lctrCisRsp_t cisRsp; /*!< CIS response. */ lctrCisInd_t cisInd; /*!< CIS indication. */ lctrCisTermInd_t cisTerm; /*!< CIS terminate indication. */ + lctrPwrCtrlReq_t pwrCtrlReq; /*!< Power control request. */ + lctrPwrCtrlRsp_t pwrCtrlRsp; /*!< Power control response. */ + lctrPwrChngInd_t pwrChngInd; /*!< Power change indication. */ } pld; /*!< Unpacked PDU payload. */ } lctrDataPdu_t; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_enc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_enc.c index a783156c09b..42b18fa8294 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_enc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_enc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master encryption packet implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master encryption packet implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.c new file mode 100644 index 00000000000..e2b8f33a474 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.c @@ -0,0 +1,242 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller isochronous stream packet implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_pdu_iso.h" +#include "util/bstream.h" +#include "hci_defs.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Unpack an ISO header. + * + * \param pHdr Unpacked packet header. + * \param pBuf Packed packet buffer. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrIsoUnpackHdr(lctrIsoHdr_t *pHdr, const uint8_t *pBuf) +{ + uint8_t len = HCI_ISO_HDR_LEN + HCI_ISO_DL_MIN_LEN; + + uint16_t field16; + + BSTREAM_TO_UINT16(field16, pBuf); + pHdr->handle = (field16 >> 0) & 0x0FFF; + pHdr->pb = (field16 >> 12) & 0x03; + pHdr->tsFlag = (field16 >> 14) & 0x01; + + BSTREAM_TO_UINT16(pHdr->len, pBuf); + + if (pHdr->tsFlag) + { + BSTREAM_TO_UINT32(pHdr->ts, pBuf); + len += HCI_ISO_TS_LEN; + } + else + { + pHdr->ts = 0; + } + + BSTREAM_TO_UINT16(pHdr->pktSn, pBuf); + BSTREAM_TO_UINT16(field16, pBuf); + + pHdr->sduLen = (field16 >> 0) & 0x0FFF; + pHdr->ps = (field16 >> 14) & 0x03; + + pHdr->pSdu = pBuf; + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack an ISO header. + * + * \param pBuf Packed packet buffer. + * \param pHdr Unpacked packet header. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrIsoPackHdr(uint8_t *pBuf, const lctrIsoHdr_t *pHdr) +{ + const uint8_t len = HCI_ISO_HDR_LEN; + uint8_t dlLen = 0; + + uint16_t field16; + + field16 = (pHdr->handle & 0x0FFF) << 0; + field16 |= (pHdr->pb & 0x03) << 12; + field16 |= (pHdr->tsFlag & 0x01) << 14; + UINT16_TO_BSTREAM(pBuf, field16); + + uint8_t *pLen = pBuf; + pBuf += sizeof(uint16_t); + + switch (pHdr->pb) + { + case LCTR_PB_COMP: + case LCTR_PB_FIRST: + dlLen = HCI_ISO_DL_MIN_LEN; + if (pHdr->tsFlag) + { + UINT32_TO_BSTREAM(pBuf, pHdr->ts); + dlLen += HCI_ISO_TS_LEN; + } + + UINT16_TO_BSTREAM(pBuf, pHdr->pktSn); + + field16 = (pHdr->sduLen & 0x0FFF) << 0; + field16 |= (pHdr->ps & 0x03) << 14; + UINT16_TO_BSTREAM(pBuf, field16); + break; + + default: + break; + } + + /* Now that length is known, pack the length. */ + UINT16_TO_BSTREAM(pLen, pHdr->len + dlLen); + + return len + dlLen; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a ISOAL Segmentation header. + * + * \param pBuf Packed packet buffer. + * \param pSegHdr Unpacked PDU header. + * + * \return Segmentation header length. + */ +/*************************************************************************************************/ +uint8_t lctrIsoPackSegHdr(uint8_t *pBuf, const lctrIsoSegHdr_t *pSegHdr) +{ + uint8_t len = LL_DATA_HDR_LEN; + + uint8_t flags = 0; + flags |= (pSegHdr->sc ) << 0; + flags |= (pSegHdr->cmplt) << 1; + UINT8_TO_BSTREAM(pBuf, flags); + + if (pSegHdr->sc == 0) + { + UINT8_TO_BSTREAM(pBuf, pSegHdr->len + LL_ISO_SEG_TO_LEN); + len += LL_ISO_SEG_TO_LEN; + UINT24_TO_BSTREAM(pBuf, pSegHdr->toffs); + } + else + { + UINT8_TO_BSTREAM(pBuf, pSegHdr->len); + } + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a ISOAL Segmentation header. + * + * \param pBuf Packed packet buffer. + * \param pHdr Unpacked PDU header. + * + * \return Segmentation header length. + */ +/*************************************************************************************************/ +uint8_t lctrIsoUnpackSegHdr(lctrIsoSegHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t len = LL_DATA_HDR_LEN; + + uint8_t flags = 0; + BSTREAM_TO_UINT8(flags, pBuf); + pHdr->sc = (flags & LL_ISOAL_SEG_HDR_MASK_SC) >> 0; + pHdr->cmplt = (flags & LL_ISOAL_SEG_HDR_MASK_CMPLT) >> 1; + BSTREAM_TO_UINT8(pHdr->len, pBuf); + + if (pHdr->sc == 0) + { + len += LL_ISO_SEG_TO_LEN; + BSTREAM_TO_UINT24(pHdr->toffs, pBuf); + } + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack an CIS data channel PDU header. + * + * \param pBuf Packed packet buffer. + * \param pHdr Unpacked PDU header. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrCisPackDataPduHdr(uint8_t *pBuf, const lctrCisDataPduHdr_t *pHdr) +{ + const uint8_t len = LL_DATA_HDR_LEN; + + uint16_t hdr = 0; + + hdr |= (pHdr->llid ) << 0; + hdr |= (pHdr->nesn & 1) << 2; + hdr |= (pHdr->sn & 1) << 3; + hdr |= (pHdr->cie & 1) << 4; + hdr |= (pHdr->np & 1) << 6; + hdr |= (pHdr->len ) << 8; + UINT16_TO_BSTREAM(pBuf, hdr); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Unpack a CIS data channel PDU header. + * + * \param pHdr Unpacked header. + * \param pBuf Packed packet buffer. + * + * \return Header length. + */ +/*************************************************************************************************/ +uint8_t lctrCisUnpackDataPduHdr(lctrCisDataPduHdr_t *pHdr, const uint8_t *pBuf) +{ + const uint8_t len = LL_DATA_HDR_LEN; + + uint16_t hdr; + + BSTREAM_TO_UINT16(hdr, pBuf); + + pHdr->llid = (hdr >> 0) & LL_DATA_HDR_LLID_MSK; + pHdr->nesn = (hdr >> 2) & 0x0001; + pHdr->sn = (hdr >> 3) & 0x0001; + pHdr->cie = (hdr >> 4) & 0x0001; + pHdr->np = (hdr >> 6) & 0x0001; + pHdr->len = (hdr >> 8) & LL_DATA_HDR_LEN_MSK; + + return len; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.h new file mode 100644 index 00000000000..3888a92ae8d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_pdu_iso.h @@ -0,0 +1,149 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller data channel packet interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef LCTR_PDU_ISO_H +#define LCTR_PDU_ISO_H + +#include "wsf_types.h" +#include "wsf_queue.h" +#include "bb_ble_api.h" +#include "ll_defs.h" +#include "ll_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Get length of ISO Header. */ +#define LCTR_GET_ISO_DATA_HDR_LEN(pIsoHdr) (HCI_ISO_HDR_LEN + (((pIsoHdr)->tsFlag) ? HCI_ISO_DL_MAX_LEN : HCI_ISO_DL_MIN_LEN)) + +/************************************************************************************************** + Constants +**************************************************************************************************/ + +/*! \brief Packet boundary flags. */ +typedef enum +{ + LCTR_PB_FIRST = 0, /*!< Data is the first fragment of a fragmented SDU. */ + LCTR_PB_CONT = 1, /*!< Data is a continuation fragment of a fragmented SDU. */ + LCTR_PB_COMP = 2, /*!< Data is a complete SDU. */ + LCTR_PB_LAST = 3 /*!< Data is the last fragment of a fragmented SDU. */ +} lctrPktBoundary_t; + +/*! \brief Packet status flags. */ +typedef enum +{ + LCTR_PS_VALID = 0, /*!< Data is received correctly. */ + LCTR_PS_INVALID = 1, /*!< Data with possible errors. */ + LCTR_PS_LOST = 2, /*!< Data with lost data. */ +} lctrPktStatus_t; + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief ISO header. */ +typedef struct +{ + /* ISO header */ + uint16_t handle; /*!< CIS or BIS handle. */ + lctrPktBoundary_t pb:8; /*!< Packet boundary flag. */ + bool_t tsFlag; /*!< Timestamp flag. */ + uint16_t len; /*!< Data length. */ + + /* ISO Data Load */ + uint32_t ts; /*!< Timestamp. */ + uint16_t pktSn; /*!< Packet sequence number. */ + uint16_t sduLen; /*!< SDU length. */ + lctrPktStatus_t ps:8; /*!< Packet status. */ + const uint8_t *pSdu; /*!< First byte of ISO SDU. */ +} lctrIsoHdr_t; + +/*! \brief ISO SDU descriptor. */ +typedef struct +{ + lctrIsoHdr_t hdr; /*!< ISO header. */ + uint32_t ts; /*!< Timestamp. */ + uint8_t data; /*!< Data. */ +} lctrSduDesc_t; + +/*! \brief ISO CIS PDU header. */ +typedef struct +{ + uint8_t llid; /*!< PDU type. */ + uint8_t nesn; /*!< Next Expected Sequence Number. */ + uint8_t sn; /*!< Sequence Number. */ + uint8_t cie; /*!< TRUE if stop next subevent. */ + uint8_t np; /*!< PDU type, whether a NULL PDU. */ + uint8_t len; /*!< Payload length. */ +} lctrCisDataPduHdr_t; + +/*! \brief ISO BIS PDU header. */ +typedef struct +{ + LlIsoLlid_t llid:8; /*!< PDU type. */ + uint8_t cssn; /*!< Control Subevent Sequence Number. */ + bool_t cstf; /*!< Control Subevent Submission Flag. */ + uint8_t len; /*!< Payload length. */ +} lctrBisDataPduHdr_t; + +/*! \brief ISOAL Segmentation Header. */ +typedef struct +{ + bool_t sc; /*!< Segment continuation flag. */ + bool_t cmplt; /*!< Segment complete flag. */ + uint8_t len; /*!< Payload length. */ + uint32_t toffs; /*!< Time offset. */ +} lctrIsoSegHdr_t; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/* Pack */ +uint8_t lctrIsoPackHdr(uint8_t *pBuf, const lctrIsoHdr_t *pHdr); +uint8_t lctrIsoPackSegHdr(uint8_t *pBuf, const lctrIsoSegHdr_t *pSegHdr); +uint8_t lctrIsoUnpackSegHdr(lctrIsoSegHdr_t *pHdr, uint8_t *pBuf); +uint8_t lctrCisPackDataPduHdr(uint8_t *pBuf, const lctrCisDataPduHdr_t *pHdr); +uint8_t lctrBisPackDataPduHdr(uint8_t *pBuf, const lctrBisDataPduHdr_t *pHdr); +uint8_t lctrBisPackBigChannelMapInd(uint8_t *pBuf, uint64_t chanMap, uint16_t instance); +uint8_t lctrBisPackBigTerminateInd(uint8_t *pBuf, uint8_t reason, uint16_t instance); + +/* Unpack */ +uint8_t lctrIsoUnpackHdr(lctrIsoHdr_t *pHdr, const uint8_t *pBuf); +uint8_t lctrCisUnpackDataPduHdr(lctrCisDataPduHdr_t *pHdr, const uint8_t *pBuf); +uint8_t lctrBisUnpackDataPduHdr(lctrBisDataPduHdr_t *pHdr, const uint8_t *pBuf); +uint8_t lctrBisUnpackBigChannelMapInd(uint64_t *pChanMap, uint16_t *pInstance, const uint8_t *pBuf); +uint8_t lctrBisUnpackBigTerminateInd(uint8_t *pReason, uint16_t *pInstance, const uint8_t *pBuf); + +#ifdef __cplusplus +}; +#endif + +#endif /* LCTR_PDU_ISO_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master.c index 266120a1b8a..4bcd7da8233 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master scan state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master scan state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -109,8 +110,6 @@ static const uint8_t lctrScanNextStateTbl[LCTR_SCAN_STATE_TOTAL][LCTR_SCAN_MSG_T * \brief Execute master scan state machine. * * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstScanExecuteSm(uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master_ae.c index c7cd31185bd..05008f5eb1f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master scan state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master scan state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -61,8 +62,8 @@ static const lctrActFn_t lctrExtScanActionTbl[LCTR_EXT_SCAN_STATE_TOTAL][LCTR_EX }, { /* LCTR_EXT_SCAN_STATE_SHUTDOWN */ NULL, /* LCTR_EXT_SCAN_MSG_RESET */ - lctrExtScanActDisallowScan, /* LCTR_EXT_SCAN_MSG_DISCOVER_ENABLE */ - lctrExtScanActDisallowScan, /* LCTR_EXT_SCAN_MSG_DISCOVER_DISABLE */ + lctrExtScanActHostEnable, /* LCTR_EXT_SCAN_MSG_DISCOVER_ENABLE */ + lctrExtScanHostDisable, /* LCTR_EXT_SCAN_MSG_DISCOVER_DISABLE */ lctrExtScanActScanTerm /* LCTR_EXT_SCAN_MSG_TERMINATE */ }, { /* LCTR_EXT_SCAN_STATE_RESET */ @@ -325,8 +326,6 @@ static const uint8_t lctrPerScanNextStateTbl[LCTR_PER_SCAN_STATE_TOTAL][LCTR_PER * * \param pExtScanCtx Extended scan context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtScanExecuteSm(lctrExtScanCtx_t *pExtScanCtx, uint8_t event) @@ -346,8 +345,6 @@ void lctrMstExtScanExecuteSm(lctrExtScanCtx_t *pExtScanCtx, uint8_t event) * \brief Execute master create sync state machine. * * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstCreateSyncExecuteSm(uint8_t event) @@ -367,8 +364,6 @@ void lctrMstCreateSyncExecuteSm(uint8_t event) * \brief Execute master transfer sync state machine. * * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstTransferSyncExecuteSm(uint8_t event) @@ -389,8 +384,6 @@ void lctrMstTransferSyncExecuteSm(uint8_t event) * * \param pPerScanCtx Periodic scanning context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstPerScanExecuteSm(lctrPerScanCtx_t *pPerScanCtx, uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave.c index b46d0b21c96..27ba51dc023 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -116,8 +117,6 @@ static const uint8_t lctrAdvNextStateTbl[LCTR_ADV_STATE_TOTAL][LCTR_ADV_MSG_TOTA * \brief Execute slave advertising state machine. * * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvAdvExecuteSm(uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave_ae.c index 7f92d706504..bda9c64e0d4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller slave advertising state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller slave advertising state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,7 +37,7 @@ typedef void (*lctrExtActFn_t)(lctrAdvSet_t *pAdvSet); /*! \brief Periodic action function call signature. */ typedef void (*lctrPerActFn_t)(lctrAdvSet_t *pAdvSet); -/*! \brief Periodic adv acad function call signature. */ +/*! \brief Periodic Adv ACAD function call signature. */ typedef void (*lctrAcadActFn_t)(lctrAdvSet_t *pAdvSet); /************************************************************************************************** @@ -175,16 +176,20 @@ static const uint8_t lctrPerAdvNextStateTbl[LCTR_PER_ADV_STATE_TOTAL][LCTR_PER_A } }; -/*! \brief Acad state machine action table */ +/*! \brief ACAD state machine action table */ static const lctrAcadActFn_t lctrAcadActionTbl[LCTR_ACAD_NUM_ID][LCTR_ACAD_COMM_MSG_TOTAL] = { { /* LCTR_ACAD_ID_CHAN_MAP_UPDATE */ lctrSlvAcadActChanMapUpdateStart, /* LCTR_ACAD_COMM_MSG_START */ lctrSlvAcadActChanMapUpdateFinish /* LCTR_ACAD_COMM_MSG_FINISH */ + }, + { /* LCTR_ACAD_ID_BIG_INFO */ + lctrSlvAcadActBigCreated, /* LCTR_ACAD_COMM_MSG_START */ + lctrSlvAcadActBigTerminated /* LCTR_ACAD_COMM_MSG_FINISH */ } }; -/*! \brief Acad state machine next state table. */ +/*! \brief ACAD state machine next state table. */ static const uint8_t lctrAcadNextStateTbl[LCTR_ACAD_STATE_TOTAL][LCTR_ACAD_COMM_MSG_TOTAL] = { { /* LCTR_ACAD_STATE_DISABLED */ @@ -204,8 +209,6 @@ static const uint8_t lctrAcadNextStateTbl[LCTR_ACAD_STATE_TOTAL][LCTR_ACAD_COMM_ * * \param pAdvSet Advertising set. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvExtAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event) @@ -226,8 +229,6 @@ void lctrSlvExtAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event) * * \param pAdvSet Advertising set. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvPeriodicAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event) @@ -244,11 +245,11 @@ void lctrSlvPeriodicAdvExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event) /*************************************************************************************************/ /*! - * \brief Get common acad event from dispatcher message. + * \brief Get common ACAD event from dispatcher message. * * \param event State machine event. * - * \return None. + * \return Comment event ID. */ /*************************************************************************************************/ static uint8_t lctrSlvGetAcadCommEvt(uint8_t event) @@ -256,9 +257,11 @@ static uint8_t lctrSlvGetAcadCommEvt(uint8_t event) switch (event) { case LCTR_ACAD_MSG_CHAN_UPDATE: + case LCTR_ACAD_MSG_BIG_CREATED: return LCTR_ACAD_COMM_MSG_START; case LCTR_ACAD_MSG_CHAN_UPDATE_FINISH: + case LCTR_ACAD_MSG_BIG_TERMINATED: return LCTR_ACAD_COMM_MSG_FINISH; default: @@ -268,11 +271,11 @@ static uint8_t lctrSlvGetAcadCommEvt(uint8_t event) /*************************************************************************************************/ /*! - * \brief Get Acad id from dispatcher message. + * \brief Get ACAD ID from dispatcher message. * * \param event State machine event. * - * \return None. + * \return ACAD ID. */ /*************************************************************************************************/ static uint8_t lctrSlvGetAcadId(uint8_t event) @@ -283,6 +286,10 @@ static uint8_t lctrSlvGetAcadId(uint8_t event) case LCTR_ACAD_MSG_CHAN_UPDATE_FINISH: return LCTR_ACAD_ID_CHAN_MAP_UPDATE; + case LCTR_ACAD_MSG_BIG_CREATED: + case LCTR_ACAD_MSG_BIG_TERMINATED: + return LCTR_ACAD_ID_BIG_INFO; + default: return LCTR_ACAD_INVALID_ID; } @@ -302,11 +309,11 @@ void lctrSlvAcadExecuteSm(lctrAdvSet_t *pAdvSet, uint8_t event) { uint8_t acadId; - if ((event = lctrSlvGetAcadCommEvt(event)) == LCTR_ACAD_COMM_MSG_INVALID) + if ((acadId = lctrSlvGetAcadId(event)) == LCTR_ACAD_INVALID_ID) { return; } - if ((acadId = lctrSlvGetAcadId(event)) == LCTR_ACAD_INVALID_ID) + if ((event = lctrSlvGetAcadCommEvt(event)) == LCTR_ACAD_COMM_MSG_INVALID) { return; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_master.c new file mode 100644 index 00000000000..aa0e79107cb --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_master.c @@ -0,0 +1,168 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller BIG state machine implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_master.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Extended action function call signature. */ +typedef void (*lctrMstBigActFn_t)(lctrBigCtx_t *pBigCtx); + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*! \brief BIG master state machine action table. */ +static const lctrMstBigActFn_t lctrMstBigActionTbl[LCTR_MST_BIG_STATE_TOTAL][LCTR_MST_BIG_MSG_TOTAL] = +{ + { /* LCTR_MST_BIG_STATE_DISABLED */ + NULL, /* LCTR_MST_BIG_MSG_RESET */ + lctrMstBigActStart, /* LCTR_MST_BIG_API_CREATE_SYNC */ + NULL, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + NULL, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + NULL, /* LCTR_MST_BIG_PDU_TERM */ + NULL, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + NULL, /* LCTR_MST_BIG_INT_MIC_FAILED */ + NULL /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SYNCING */ + lctrMstBigActShutdown, /* LCTR_MST_BIG_MSG_RESET */ + NULL, /* LCTR_MST_BIG_API_CREATE_SYNC */ + lctrMstBigActShutdown, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + lctrMstBigActBigSync, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + NULL, /* LCTR_MST_BIG_PDU_TERM */ + NULL, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + NULL, /* LCTR_MST_BIG_INT_MIC_FAILED */ + NULL /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SYNCED */ + lctrMstBigActShutdown, /* LCTR_MST_BIG_MSG_RESET */ + NULL, /* LCTR_MST_BIG_API_CREATE_SYNC */ + lctrMstBigActShutdown, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + NULL, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + lctrMstBigActTerm, /* LCTR_MST_BIG_PDU_TERM */ + lctrMstBigActSyncLost, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + lctrMstBigActMicFailed, /* LCTR_MST_BIG_INT_MIC_FAILED */ + lctrMstBigActCleanup /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SHUTDOWN */ + NULL, /* LCTR_MST_BIG_MSG_RESET */ + NULL, /* LCTR_MST_BIG_API_CREATE_SYNC */ + NULL, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + NULL, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + NULL, /* LCTR_MST_BIG_PDU_TERM */ + NULL, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + NULL, /* LCTR_MST_BIG_INT_MIC_FAILED */ + lctrMstBigActCleanup /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_EXT_ADV_STATE_RESET */ + NULL, /* LCTR_MST_BIG_MSG_RESET */ + NULL, /* LCTR_MST_BIG_API_CREATE_SYNC */ + NULL, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + NULL, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + NULL, /* LCTR_MST_BIG_PDU_TERM */ + NULL, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + NULL, /* LCTR_MST_BIG_INT_MIC_FAILED */ + lctrMstBigActCleanup /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + } +}; + +/*! \brief BIG master state machine next state table. */ +static const uint8_t lctrMstBigNextStateTbl[LCTR_MST_BIG_STATE_TOTAL][LCTR_MST_BIG_MSG_TOTAL] = +{ + { /* LCTR_MST_BIG_STATE_DISABLED */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_MSG_RESET */ + LCTR_MST_BIG_STATE_SYNCING, /* LCTR_MST_BIG_API_CREATE_SYNC */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_PDU_TERM */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + LCTR_MST_BIG_STATE_DISABLED, /* LCTR_MST_BIG_INT_MIC_FAILED */ + LCTR_MST_BIG_STATE_DISABLED /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SYNCING */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_MSG_RESET */ + LCTR_MST_BIG_STATE_SYNCING, /* LCTR_MST_BIG_API_CREATE_SYNC */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + LCTR_MST_BIG_STATE_SYNCED, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + LCTR_MST_BIG_STATE_SYNCING, /* LCTR_MST_BIG_PDU_TERM */ + LCTR_MST_BIG_STATE_SYNCING, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_INT_MIC_FAILED */ + LCTR_MST_BIG_STATE_SYNCING /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SYNCED */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_MSG_RESET */ + LCTR_MST_BIG_STATE_SYNCED, /* LCTR_MST_BIG_API_CREATE_SYNC */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + LCTR_MST_BIG_STATE_SYNCED, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_PDU_TERM */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_INT_MIC_FAILED */ + LCTR_MST_BIG_STATE_DISABLED /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_SHUTDOWN */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_MSG_RESET */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_API_CREATE_SYNC */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_PDU_TERM */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + LCTR_MST_BIG_STATE_SHUTDOWN, /* LCTR_MST_BIG_INT_MIC_FAILED */ + LCTR_MST_BIG_STATE_SHUTDOWN /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + }, + { /* LCTR_MST_BIG_STATE_RESET */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_MSG_RESET */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_API_CREATE_SYNC */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_API_TERMINATE_SYNC */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_ACAD_BIG_INFO */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_PDU_TERM */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_INT_SYNC_TIMEOUT */ + LCTR_MST_BIG_STATE_RESET, /* LCTR_MST_BIG_INT_MIC_FAILED */ + LCTR_MST_BIG_STATE_RESET /* LCTR_MST_BIG_INT_TERMINATED_SYNC */ + } +}; + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute BIG main state machine. + * + * \param pBigCtx BIG context. + * \param event State machine event. + *************************************************************************************************/ +void lctrMstBigExecuteSm(lctrBigCtx_t *pBigCtx, LctrMstBigMsg_t event) +{ + LL_TRACE_INFO3("lctrMstBigExecuteSm: bigHandle=%u, state=%u, event=%u", pBigCtx->handle, pBigCtx->state, event); + + if (lctrMstBigActionTbl[pBigCtx->state][event]) + { + lctrMstBigActionTbl[pBigCtx->state][event](pBigCtx); + } + + pBigCtx->state = lctrMstBigNextStateTbl[pBigCtx->state][event]; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_slave.c new file mode 100644 index 00000000000..a4bd7a4ae1c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_bis_slave.c @@ -0,0 +1,129 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller BIG state machine implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_bis_slave.h" +#include "sch_api.h" +#include "wsf_assert.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Extended action function call signature. */ +typedef void (*lctrSlvBigActFn_t)(lctrBigCtx_t *pBigCtx); + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*! \brief BIS slave state machine action table. */ +static const lctrSlvBigActFn_t lctrSlvBigActionTbl[LCTR_SLV_BIG_STATE_TOTAL][LCTR_SLV_BIG_MSG_TOTAL] = +{ + { /* LCTR_SLV_BIG_STATE_DISABLED */ + NULL, /* LCTR_SLV_BIG_MSG_RESET */ + lctrSlvBigActStart, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + NULL, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + NULL, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + NULL /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_SLV_BIG_STATE_ENABLED */ + lctrSlvBigActShutdown, /* LCTR_SLV_BIG_MSG_RESET */ + NULL, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + lctrSlvBigActSendChMapUpd, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + lctrSlvBigActSendTerm, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + NULL /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_SLV_BIG_STATE_SHUTDOWN */ + NULL, /* LCTR_SLV_BIG_MSG_RESET */ + NULL, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + NULL, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + lctrSlvBigActSendTerm, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + lctrSlvBigActCleanup /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_EXT_ADV_STATE_RESET */ + NULL, /* LCTR_SLV_BIG_MSG_RESET */ + NULL, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + NULL, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + NULL, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + lctrSlvBigActCleanup /* LCTR_SLV_BIG_MSG_TERMINATED */ + } +}; + +/*! \brief BIS slave state machine next state table. */ +static const uint8_t lctrSlvBigNextStateTbl[LCTR_SLV_BIG_STATE_TOTAL][LCTR_SLV_BIG_MSG_TOTAL] = +{ + { /* LCTR_SLV_BIG_STATE_DISABLED */ + LCTR_SLV_BIG_STATE_DISABLED, /* LCTR_SLV_BIG_MSG_RESET */ + LCTR_SLV_BIG_STATE_ENABLED, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + LCTR_SLV_BIG_STATE_DISABLED, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + LCTR_SLV_BIG_STATE_DISABLED, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + LCTR_SLV_BIG_STATE_DISABLED /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_SLV_BIG_STATE_ENABLED */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_RESET */ + LCTR_SLV_BIG_STATE_ENABLED, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + LCTR_SLV_BIG_STATE_ENABLED, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + LCTR_SLV_BIG_STATE_SHUTDOWN, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + LCTR_SLV_BIG_STATE_DISABLED, /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_SLV_BIG_STATE_SHUTDOWN */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_RESET */ + LCTR_SLV_BIG_STATE_SHUTDOWN, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + LCTR_SLV_BIG_STATE_SHUTDOWN, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + LCTR_SLV_BIG_STATE_SHUTDOWN, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + LCTR_SLV_BIG_STATE_DISABLED /* LCTR_SLV_BIG_MSG_TERMINATED */ + }, + { /* LCTR_SLV_BIG_STATE_RESET */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_RESET */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_CREATE_BIG */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_CH_MAP_UPD */ + LCTR_SLV_BIG_STATE_RESET, /* LCTR_SLV_BIG_MSG_TERMINATE_BIG */ + LCTR_SLV_BIG_STATE_DISABLED /* LCTR_SLV_BIG_MSG_TERMINATED */ + } +}; + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute BIG main state machine. + * + * \param pBigCtx BIS context. + * \param event State machine event. + */ +/*************************************************************************************************/ +void lctrSlvBigExecuteSm(lctrBigCtx_t *pBigCtx, uint8_t event) +{ + LL_TRACE_INFO3("lctrSlvBigExecuteSm: bigHandle=%u, state=%u, event=%u", pBigCtx->handle, pBigCtx->state, event); + + if (lctrSlvBigActionTbl[pBigCtx->state][event]) + { + lctrSlvBigActionTbl[pBigCtx->state][event](pBigCtx); + } + + pBigCtx->state = lctrSlvBigNextStateTbl[pBigCtx->state][event]; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_cis.c new file mode 100644 index 00000000000..6499914c51c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_cis.c @@ -0,0 +1,169 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS main state machine implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis.h" +#include "lctr_api_conn.h" +#include "sch_api.h" +#include "wsf_assert.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Get remapped event. + * + * \param pCisCtx CIS Context. + * \param event Subsystem event. + * + * \return Procedure event ID. + */ +/*************************************************************************************************/ +static uint8_t lctrRemapEvent(lctrCisCtx_t *pCisCtx, uint8_t event) +{ + switch (event) + { + /*** Peer messages ***/ + + /*** Host messages ***/ + + case LCTR_CONN_MSG_API_DISCONNECT: + { + lctrCisStoreDisconnectReason(pCisCtx); + return LCTR_CIS_MSG_CIS_DISC; + } + + /*** Internal messages ***/ + case LCTR_CONN_TERM_SUP_TIMEOUT: + { + lctrCisStoreConnTimeoutTerminateReason(pCisCtx); + return LCTR_CIS_MSG_CIS_CONN_FAIL; + } + case LCTR_CIS_MSG_CIS_TERM_MIC_FAILED: + { + lctrCisStoreMicFailedTerminateReason(pCisCtx); + return LCTR_CIS_MSG_CIS_CONN_FAIL; + } + case LCTR_CIS_MSG_CIS_EST: + return LCTR_CIS_MSG_CIS_EST; + case LCTR_CIS_MSG_CIS_EST_FAIL: + return LCTR_CIS_MSG_CIS_EST_FAIL; + case LCTR_CIS_MSG_CIS_CLOSED: + return LCTR_CIS_MSG_CIS_CLOSED; + + default: + break; + } + return LCTR_CIS_MSG_INVALID; +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute CIS main state machine. + * + * \param pCisCtx CIS context. + * \param event State machine event. + *************************************************************************************************/ +void lctrCisExecuteSm(lctrCisCtx_t *pCisCtx, uint8_t event) +{ + if ((event = lctrRemapEvent(pCisCtx, event)) == LCTR_CIS_MSG_INVALID) + { + return; + } + + LL_TRACE_INFO3("lctrCisExecuteSm: handle=%d state=%u, event=%u", pCisCtx->cisHandle, pCisCtx->state, event); + + switch (pCisCtx->state) + { + case LCTR_CIS_STATE_IDLE: + switch (event) + { + case LCTR_CIS_MSG_CIS_EST: + lctrCisActCisEst(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_EST; + break; + case LCTR_CIS_MSG_CIS_EST_FAIL: + lctrCisActCisEstFail(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_IDLE; + break; + default: + LL_TRACE_INFO1("Invalid event in the LCTR_CIS_STATE_IDLE, event=%u", event); + break; + } + break; + + case LCTR_CIS_STATE_EST: + switch (event) + { + case LCTR_CIS_MSG_CIS_DISC: + lctrCisActDisc(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_SHUTDOWN; + break; + case LCTR_CIS_MSG_CIS_CONN_FAIL: + lctrCisActFail(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_IDLE; + break; + case LCTR_CIS_MSG_CIS_CLOSED: + lctrCisActClosed(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_IDLE; + break; + + default: + LL_TRACE_INFO1("Invalid event in the LCTR_CIS_STATE_EST, event=%u", event); + break; + } + break; + + case LCTR_CIS_STATE_SHUTDOWN: + switch (event) + { + case LCTR_CIS_MSG_CIS_CLOSED: + lctrCisActClosed(pCisCtx); + pCisCtx->state = LCTR_CIS_STATE_IDLE; + break; + + default: + LL_TRACE_INFO1("Invalid event in the LCTR_CIS_STATE_SHUTDOWN, event=%u", event); + break; + } + break; + + default: + break; + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_master.c index 9c48eff6926..555b587deff 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master connection state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master connection state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,8 +37,6 @@ * * \param pCtx Connection context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstConnExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) @@ -128,8 +127,10 @@ void lctrMstConnExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) { case LCTR_CONN_TERMINATED: LL_TRACE_INFO2("lctrMstConnExecuteSm: handle=%u, state=%u, event=TERMINATED", LCTR_GET_CONN_HANDLE(pCtx), pCtx->state); - SchRmRemove(LCTR_GET_CONN_HANDLE(pCtx)); lctrNotifyHostDisconnectInd(pCtx); + /* Fallthrough. */ + case LCTR_CONN_INIT_CANCELED: + SchRmRemove(LCTR_GET_CONN_HANDLE(pCtx)); lctrFreeConnCtx(pCtx); break; default: diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_slave.c index 683626b66c1..6314ccb056a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller connection state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller connection state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,6 +27,7 @@ #include "lctr_int_adv_slave.h" #include "lmgr_api_conn.h" #include "sch_api.h" +#include "sch_api_ble.h" #include "wsf_assert.h" #include "wsf_trace.h" @@ -35,8 +37,6 @@ * * \param pCtx Connection context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvConnExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) @@ -129,7 +129,7 @@ void lctrSlvConnExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) case LCTR_CONN_STATE_ESTABLISHED_STARTUP: LL_TRACE_INFO1("lctrSlvConnExecuteSm: state=ESTABLISHED_STARTUP, event=%u", event); - switch(event) + switch (event) { case LCTR_CONN_SLV_INIT_STARTUP_LLCP: pCtx->state = LCTR_CONN_STATE_ESTABLISHED_READY; @@ -216,8 +216,6 @@ void lctrSlvConnExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) * * \param pCtx Connection context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrConnStatelessEventHandler(lctrConnCtx_t *pCtx, uint8_t event) @@ -226,6 +224,11 @@ void lctrConnStatelessEventHandler(lctrConnCtx_t *pCtx, uint8_t event) { case LCTR_CONN_TERMINATED: LL_TRACE_INFO2("lctrConnStatelessEventHandler: handle=%u, state=%u, event=TERMINATED", LCTR_GET_CONN_HANDLE(pCtx), pCtx->state); + if (pCtx->role == LL_ROLE_SLAVE) + { + SchTmRemove(LCTR_GET_CONN_HANDLE(pCtx)); + } + lctrNotifyHostDisconnectInd(pCtx); lctrFreeConnCtx(pCtx); break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master.c index 2f962e44396..a5c2be40294 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master initiate state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master initiate state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -100,8 +101,6 @@ static const uint8_t lctrInitNextStateTbl[LCTR_INIT_STATE_TOTAL][LCTR_INIT_MSG_T * \brief Execute master scan and initiate state machine. * * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstInitExecuteSm(uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master_ae.c index 14cc3562510..0e1ad283d77 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_init_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master initiate state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master initiate state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -102,8 +103,6 @@ static const uint8_t lctrExtInitNextStateTbl[LCTR_EXT_INIT_STATE_TOTAL][LCTR_EXT * * \param pExtInitCtx Extended scanning context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstExtInitExecuteSm(lctrExtScanCtx_t *pExtInitCtx, uint8_t event) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis.c new file mode 100644 index 00000000000..b2a1a9a2ae5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis.c @@ -0,0 +1,328 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS LLCP state machine implementation file shared by master + * and slave. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis_master.h" +#include "lctr_int_conn_master.h" +#include "lctr_int_conn.h" +#include "lmgr_api.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "util/bstream.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Action function call signature. */ +typedef void (*lctrActFn_t)(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief CIS termination state machine action table. */ +static const lctrActFn_t lctrCisTermActionTbl[LCTR_CIS_TERM_STATE_TOTAL][LCTR_CIS_TERM_EVENT_TOTAL] = +{ + { /* LCTR_CIS_TERM_STATE_IDLE */ + lctrCisLlcpActHostDisc, /* LCTR_CIS_TERM_EVENT_HOST_DISC */ + lctrCisLlcpActPeerDisc, /* LCTR_CIS_TERM_EVENT_PEER_DISC */ + lctrCisLlcpActIntHostDisc, /* LCTR_CIS_TERM_EVENT_INT_START_DISC */ + lctrCisLlcpActIntPeerDisc, /* LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC */ + NULL /* LCTR_CIS_TERM_EVENT_CIS_TERM */ + }, + { /* LCTR_CIS_TERM_STATE_TERMINATING */ + NULL, /* LCTR_CIS_TERM_EVENT_HOST_DISC */ + NULL, /* LCTR_CIS_TERM_EVENT_PEER_DISC */ + NULL, /* LCTR_CIS_TERM_EVENT_INT_START_DISC */ + NULL, /* LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC */ + lctrCisLlcpActCisTerm /* LCTR_CIS_TERM_EVENT_CIS_TERM */ + } +}; + +/*! \brief CIS termination state machine next state table. */ +static const uint8_t lctrCisTermNextStateTbl[LCTR_CIS_TERM_STATE_TOTAL][LCTR_CIS_TERM_EVENT_TOTAL] = +{ + { /* LCTR_CIS_TERM_STATE_IDLE */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_HOST_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_PEER_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_INT_START_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC */ + LCTR_CIS_TERM_STATE_IDLE /* LCTR_CIS_TERM_EVENT_CIS_TERM */ + }, + { /* LCTR_CIS_TERM_STATE_TERMINATING */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_HOST_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_PEER_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_INT_START_DISC */ + LCTR_CIS_TERM_STATE_TERMINATING, /* LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC */ + LCTR_CIS_TERM_STATE_IDLE /* LCTR_CIS_TERM_EVENT_CIS_TERM */ + } +}; + + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief CIS executes termination action function. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + * \param event Event ID. + */ +/*************************************************************************************************/ +static inline void lctrExecTermAction(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t event) +{ + if (lctrCisTermActionTbl[pCisCtx->termState][event]) + { + lctrCisTermActionTbl[pCisCtx->termState][event](pCtx, pCisCtx); + } + + pCisCtx->termState = lctrCisTermNextStateTbl[pCisCtx->termState][event]; +} + +/*************************************************************************************************/ +/*! + * \brief Get remapped event. This function also updates the CIS handle for the LLCP. + * + * \param event Subsystem event. + * \param pCtx Connection context. + * + * \return Procedure event ID. + */ +/*************************************************************************************************/ +static uint8_t lctrRemapTermEvent(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + /*** Peer messages ***/ + + case LCTR_CONN_MSG_RX_LLCP: + switch (lctrDataPdu.opcode) + { + case LL_PDU_CIS_TERM_IND: + { + lctrCisCtx_t *pCisCtx = lctrFindCisById(lctrDataPdu.pld.cisTerm.cigId, lctrDataPdu.pld.cisTerm.cisId); + pCtx->llcpCisHandle = pCisCtx->cisHandle; /* Update LLCP CIS handle for connection context from peer. */ + return LCTR_CIS_TERM_EVENT_PEER_DISC; + } + break; + + default: + break; + } + break; + + /*** Host messages ***/ + + case LCTR_CONN_MSG_API_DISCONNECT: + { + lctrCisCtx_t *pCisCtx; + + if ((pCisCtx = lctrFindCisByHandle(pLctrConnMsg->cisDisc.cisHandle)) != NULL) + { + pCtx->llcpCisHandle = pLctrConnMsg->cisDisc.cisHandle; /* Update LLCP CIS handle for connection context from host. */ + pLctrConnMsg->cisDisc.cisHandle = 0; + return LCTR_CIS_TERM_EVENT_HOST_DISC; + } + break; + } + /*** Internal messages ***/ + + case LCTR_CIS_TERM_EVENT_CIS_TERM: + return LCTR_CIS_TERM_EVENT_CIS_TERM; + + case LCTR_CONN_LLCP_START_PENDING: + if (pCtx->llcpPendMask & (1 << LCTR_PROC_CIS_TERM)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_CIS_TERM); + return LCTR_CIS_TERM_EVENT_INT_START_DISC; + } + if (pCtx->llcpPendMask & (1 << LCTR_PROC_CIS_TERM_PEER)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_CIS_TERM_PEER); + return LCTR_CIS_TERM_EVENT_INT_START_PEER_DISC; + } + break; + + default: + break; + } + return LCTR_CIS_TERM_EVENT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Resolve procedure collision. + * + * \param event Subsystem event. + * \param pCisCtx CIS context. + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +static void lctrResolveCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CIS_TERM_EVENT_PEER_DISC: + if ((pCtx->llcpActiveProc == LCTR_PROC_CMN_CH_MAP_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_PHY_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_CONN_PARAM)) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_DIFFERENT_TRANSACTION_COLLISION, TRUE); + } + else + { + lctrCisStoreTerminateReason(pCisCtx); + pCtx->llcpPendMask |= 1 << LCTR_PROC_CIS_TERM_PEER; + LL_TRACE_INFO2("Pending CIS_TERM_IND=%u procedure: activeProc=%u", LCTR_PROC_CIS_TERM_PEER, pCtx->llcpActiveProc); + } + break; + + case LCTR_CIS_TERM_EVENT_HOST_DISC: + pCtx->llcpNotifyMask |= 1 << LCTR_PROC_CIS_TERM; + pCtx->llcpPendMask |= 1 << LCTR_PROC_CIS_TERM; + LL_TRACE_INFO2("Pending CIS_TERM_IND=%u procedure: activeProc=%u", LCTR_PROC_CIS_TERM, pCtx->llcpActiveProc); + break; + + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if active procedure can be overridden with CIS termination procedure. + * + * \param pCtx Connection context. + * \param event Subsystem event. + * + * This routine will pend the active procedure and allow the phy update procedure to + * override it. + */ +/*************************************************************************************************/ +static void lctrCheckProcOverride(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CIS_TERM_EVENT_PEER_DISC: + /* Only the procedure without instant fields can be overridden. */ + switch (pCtx->llcpActiveProc) + { + case LCTR_PROC_CMN_VER_EXCH: + case LCTR_PROC_CMN_FEAT_EXCH: + case LCTR_PROC_CMN_DATA_LEN_UPD: + case LCTR_PROC_CMN_REQ_PEER_SCA: + pCtx->llcpPendMask |= 1 << pCtx->llcpActiveProc; + pCtx->llcpActiveProc = LCTR_PROC_CIS_TERM; + pCtx->llcpIsOverridden = TRUE; + break; + + default: + break; + } + break; + + default: + break; + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute CIS termination state machine. + * + * \param pCtx Connection context. + * \param event State machine event. + * + * \return TRUE if the event is handled by this state machine, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrLlcpExecuteCisTermSm(lctrConnCtx_t *pCtx, uint8_t event) +{ + if ((event = lctrRemapTermEvent(pCtx, event)) == LCTR_CIS_TERM_EVENT_INVALID) + { + return FALSE; + } + + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(pCtx->llcpCisHandle); + + WSF_ASSERT(pCisCtx != NULL) + + switch (pCtx->llcpState) + { + case LCTR_LLCP_STATE_IDLE: + LL_TRACE_INFO3("lctrLlcpExecuteCisTermSm: cis_handle=%u, llcpState=IDLE, termState=%u, event=%u", pCisCtx->cisHandle, pCisCtx->termState, event); + + lctrExecTermAction(pCtx, pCisCtx, event); + + if (pCisCtx->termState != LCTR_CIS_TERM_STATE_IDLE) + { + pCtx->llcpState = LCTR_LLCP_STATE_BUSY; + pCtx->llcpActiveProc = LCTR_PROC_CIS_TERM; + } + break; + + case LCTR_LLCP_STATE_BUSY: + LL_TRACE_INFO3("lctrLlcpExecuteCisTermSm: cis_handle=%u, llcpState=BUSY, termState=%u, event=%u", pCisCtx->cisHandle, pCisCtx->termState, event); + + lctrCheckProcOverride(pCtx, event); + + if (pCtx->llcpActiveProc == LCTR_PROC_CIS_TERM) + { + lctrExecTermAction(pCtx, pCisCtx, event); + + if (pCisCtx->termState == LCTR_CIS_TERM_STATE_IDLE) + { + lctrCisStopLlcpTimer(pCtx, pCisCtx); + pCtx->llcpState = LCTR_LLCP_STATE_IDLE; + pCtx->llcpActiveProc = LCTR_PROC_INVALID; + + lctrStartPendingLlcp(pCtx); + } + } + else + { + lctrResolveCollision(pCtx, pCisCtx, event); + } + break; + + default: + break; + } + + return TRUE; +} + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_master.c new file mode 100644 index 00000000000..1a625680387 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_master.c @@ -0,0 +1,297 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS LLCP master state machine implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis_master.h" +#include "lctr_int_conn_master.h" +#include "lctr_int_conn.h" +#include "lmgr_api.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "util/bstream.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Action function call signature. */ +typedef void (*lctrActFn_t)(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/*! \brief CIS establishment procedure events. */ +enum +{ + LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ, /*!< Received host LL_CIS_REQ command. */ + LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP, /*!< Received peer LL_CIS_RSP. */ + LCTR_CIS_MST_EST_EVENT_PEER_REJECT, /*!< Received peer LL_REJECT_IND_EXT or LL_UNKNOWN_RSP. */ + LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT, /*!< Received internal response timeout. */ + LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT, /*!< Received local rejection due to limited resources. */ + LCTR_CIS_MST_EST_EVENT_TOTAL, /*!< Total CIS events. */ + LCTR_CIS_MST_EST_EVENT_INVALID = 0xFF /*!< Invalid event. */ +}; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +static void lctrMstCisLlcpActRejectCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief CIS establishment state machine action table. */ +static const lctrActFn_t lctrMstCisEstActionTbl[LCTR_CIS_MST_EST_STATE_TOTAL][LCTR_CIS_MST_EST_EVENT_TOTAL] = +{ + { /* LCTR_CIS_MST_EST_STATE_IDLE */ + lctrMstCisLlcpActHostCisReq, /* LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ */ + lctrMstCisLlcpActRejectCollision, /* LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP */ /* Shall not happen */ + lctrMstCisLlcpActRejectCollision, /* LCTR_CIS_MST_EST_EVENT_PEER_REJECT */ /* Shall not happen */ + NULL, /* LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT */ /* Shall not happen */ + NULL, /* LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT */ /* Shall not happen */ + }, + { /* LCTR_CIS_MST_EST_STATE_CIS_RSP */ + NULL, /* LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ */ + lctrMstCisLlcpActPeerCisRsp, /* LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP */ + lctrMstCisLlcpActPeerRej, /* LCTR_CIS_MST_EST_EVENT_PEER_REJECT */ + lctrMstCisLlcpActRspTimeout, /* LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT */ + lctrMstCisLlcpActLocalReject, /* LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT */ + } +}; + +/*! \brief CIS establishment state machine next state table. */ +static const uint8_t lctrMstCisEstNextStateTbl[LCTR_CIS_MST_EST_STATE_TOTAL][LCTR_CIS_MST_EST_EVENT_TOTAL] = +{ + { /* LCTR_CIS_MST_EST_STATE_IDLE */ + LCTR_CIS_MST_EST_STATE_CIS_RSP, /* LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_PEER_REJECT */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT */ + }, + { /* LCTR_CIS_MST_EST_STATE_CIS_RSP */ + LCTR_CIS_MST_EST_STATE_CIS_RSP, /* LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_PEER_REJECT */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT */ + LCTR_CIS_MST_EST_STATE_IDLE, /* LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT */ + } +}; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Send peer LL_REJECT_IND_EXT due to pending operation. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrMstCisLlcpActRejectCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + LL_TRACE_WARN1("Peer requested PHY while procedure pending, handle=%u", LCTR_GET_CONN_HANDLE(pCtx)); + lctrSendRejectInd(pCtx, LL_ERROR_CODE_LMP_ERR_TRANSACTION_COLLISION, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief Execute action function. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + * \param event Event ID. + */ +/*************************************************************************************************/ +static inline void lctrExecAction(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t event) +{ + if (lctrMstCisEstActionTbl[pCisCtx->estState][event]) + { + lctrMstCisEstActionTbl[pCisCtx->estState][event](pCtx, pCisCtx); + } + + pCisCtx->estState = lctrMstCisEstNextStateTbl[pCisCtx->estState][event]; +} + +/*************************************************************************************************/ +/*! + * \brief Get remapped event. This function also update the CIS handle for the LLCP. + * + * \param event Subsystem event. + * \param pCtx Connection context. + * + * \return Procedure event ID. + */ +/*************************************************************************************************/ +static uint8_t lctrRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + /*** Peer messages ***/ + + case LCTR_CONN_MSG_RX_LLCP: + switch (lctrDataPdu.opcode) + { + case LL_PDU_CIS_RSP: + return LCTR_CIS_MST_EST_EVENT_PEER_CIS_RSP; + case LL_PDU_UNKNOWN_RSP: + if (lctrDataPdu.pld.unknownRsp.unknownType == LL_PDU_CIS_REQ) + { + return LCTR_CIS_MST_EST_EVENT_PEER_REJECT; + } + break; + case LL_PDU_REJECT_EXT_IND: + if (lctrDataPdu.pld.rejInd.opcode == LL_PDU_CIS_REQ) + { + return LCTR_CIS_MST_EST_EVENT_PEER_REJECT; + } + break; + break; + + default: + break; + } + break; + + /*** Host messages ***/ + + case LCTR_CONN_MSG_API_CIS_REQ: + pCtx->llcpCisHandle = pLctrConnMsg->createCis.cisHandle; /* Update LLCP CIS handle for connection context from host. */ + return LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ; + + /*** Internal messages ***/ + case LCTR_CONN_LLCP_START_PENDING: + if (pCtx->llcpPendMask & (1 << LCTR_PROC_CIS_EST)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_CIS_EST); + return LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ; + } + break; + + case LCTR_CONN_TMR_CIS_LLCP_RSP_EXP: + return LCTR_CIS_MST_EST_EVENT_RSP_TIMEOUT; + + case LCTR_CONN_TERM_CIS_LOCAL_RESOURCE: + return LCTR_CIS_MST_EST_EVENT_LOCAL_REJECT; + + default: + break; + } + return LCTR_CIS_MST_EST_EVENT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Resolve procedure collision. + * + * \param event Subsystem event. + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CIS_MST_EST_EVENT_HOST_CIS_REQ: + pCtx->llcpNotifyMask |= 1 << LCTR_PROC_CIS_EST; + pCtx->llcpPendMask |= 1 << LCTR_PROC_CIS_EST; + LL_TRACE_INFO2("Pending CIS_REQ=%u procedure: activeProc=%u", LCTR_PROC_CIS_EST, pCtx->llcpActiveProc); + break; + + default: + break; + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute CIS master establishment LLCP state machine. + * + * \param pCtx Connection context. + * \param event State machine event. + * + * \return TRUE if the event is handled by this state machine, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrMstLlcpExecuteCisEstSm(lctrConnCtx_t *pCtx, uint8_t event) +{ + if ((event = lctrRemapEvent(pCtx, event)) == LCTR_CIS_MST_EST_EVENT_INVALID) + { + return FALSE; + } + + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(pCtx->llcpCisHandle); + WSF_ASSERT(pCisCtx != NULL) + + switch (pCtx->llcpState) + { + case LCTR_LLCP_STATE_IDLE: + LL_TRACE_INFO3("lctrMstLlcpExecuteCisEstSm: cis_handle=%u, llcpState=IDLE, estState=%u, event=%u", pCisCtx->cisHandle, pCisCtx->estState, event); + + lctrExecAction(pCtx, pCisCtx, event); + + if (pCisCtx->estState != LCTR_CIS_MST_EST_STATE_IDLE) + { + pCtx->llcpState = LCTR_LLCP_STATE_BUSY; + pCtx->llcpActiveProc = LCTR_PROC_CIS_EST; + } + break; + + case LCTR_LLCP_STATE_BUSY: + LL_TRACE_INFO3("lctrMstLlcpExecuteCisEstSm: cis_handle=%u, llcpState=BUSY, estState=%u, event=%u", pCisCtx->cisHandle, pCisCtx->estState, event); + + if (pCtx->llcpActiveProc == LCTR_PROC_CIS_EST) + { + lctrExecAction(pCtx, pCisCtx, event); + + if (pCisCtx->estState == LCTR_CIS_MST_EST_STATE_IDLE) + { + lctrCisStopLlcpTimer(pCtx, pCisCtx); + pCtx->llcpState = LCTR_LLCP_STATE_IDLE; + pCtx->llcpActiveProc = LCTR_PROC_INVALID; + + lctrStartPendingLlcp(pCtx); + } + } + else + { + lctrResolveCollision(pCtx, event); + } + + break; + + default: + break; + } + + return TRUE; +} + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_slave.c new file mode 100644 index 00000000000..30c7929433a --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_cis_slave.c @@ -0,0 +1,382 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer controller CIS LLCP slave state machine implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_cis_slave.h" +#include "lctr_int_conn.h" +#include "lctr_int_conn_master.h" +#include "lctr_int_conn_slave.h" +#include "lmgr_api.h" +#include "wsf_assert.h" +#include "wsf_trace.h" +#include "util/bstream.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ +/*! \brief Action function call signature. */ +typedef void (*lctrActFn_t)(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/*! \brief Slave CIS establishment events. */ +enum +{ + LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ, /*!< Received peer LL_CIS_REQ. */ + LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ, /*!< Received internal peer LL_CIS_REQ. */ + LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT, /*!< Received host LE CIS Request Accept command. */ + LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT, /*!< Received host LE CIS Request Reject command. */ + LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND, /*!< Received peer LL_CIS_IND. */ + LCTR_CIS_SLV_EST_EVENT_PEER_REJECT, /*!< Received peer LL_REJECT_IND_EXT or LL_UNKNOWN_RSP. */ + LCTR_CIS_SLV_EST_EVENT_TOTAL, /*!< Total CIS events. */ + LCTR_CIS_SLV_EST_EVENT_INVALID = 0xFF /*!< Invalid event. */ +}; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ +static void lctrSlvCisLlcpActRejectCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx); + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief CIS establishment state machine action table. */ +static const lctrActFn_t lctrSlvCisEstActionTbl[LCTR_CIS_SLV_EST_STATE_TOTAL][LCTR_CIS_SLV_EST_EVENT_TOTAL] = +{ + { /* LCTR_CIS_SLV_EST_STATE_IDLE */ + lctrSlvCisLlcpActPeerCisReq, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + lctrSlvCisLlcpActIntPeerCisReq, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + NULL /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + }, + { /* LCTR_CIS_SLV_EST_STATE_HOST_REPLY */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + lctrSlvCisLlcpActRejectCollision, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + lctrSlvCisLlcpActAcpCisReq, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + lctrSlvCisLlcpActRejCisReq, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + NULL /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + }, + { /* LCTR_CIS_SLV_EST_STATE_CIS_IND */ + lctrSlvCisLlcpActRejectCollision, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + NULL, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + lctrSlvCisLlcpActPeerCisInd, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + lctrSlvCisLlcpActPeerCisRej /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + } +}; + +/*! \brief CIS establishment state machine next state table. */ +static const uint8_t lctrSlvCisEstNextStateTbl[LCTR_CIS_SLV_EST_STATE_TOTAL][LCTR_CIS_SLV_EST_EVENT_TOTAL] = +{ + { /* LCTR_CIS_SLV_EST_STATE_IDLE */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_IDLE, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + LCTR_CIS_SLV_EST_STATE_IDLE, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + LCTR_CIS_SLV_EST_STATE_IDLE, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + LCTR_CIS_SLV_EST_STATE_IDLE /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + }, + { /* LCTR_CIS_SLV_EST_STATE_HOST_REPLY */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + LCTR_CIS_SLV_EST_STATE_IDLE, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + LCTR_CIS_SLV_EST_STATE_HOST_REPLY /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + }, + { /* LCTR_CIS_SLV_EST_STATE_CIS_IND */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /* LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /* LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT */ + LCTR_CIS_SLV_EST_STATE_CIS_IND, /* LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT */ + LCTR_CIS_SLV_EST_STATE_IDLE, /* LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND */ + LCTR_CIS_SLV_EST_STATE_IDLE /* LCTR_CIS_SLV_EST_EVENT_PEER_REJECT */ + } +}; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ +/*************************************************************************************************/ +/*! + * \brief Send peer LL_REJECT_IND_EXT due to pending operation. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + */ +/*************************************************************************************************/ +static void lctrSlvCisLlcpActRejectCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx) +{ + LL_TRACE_WARN1("Peer requested PHY while procedure pending, handle=%u", LCTR_GET_CONN_HANDLE(pCtx)); + lctrSendRejectInd(pCtx, LL_ERROR_CODE_LMP_ERR_TRANSACTION_COLLISION, TRUE); +} + +/*************************************************************************************************/ +/*! + * \brief Execute action function. + * + * \param pCtx Connection context. + * \param pCisCtx CIS context. + * \param event Event ID. + */ +/*************************************************************************************************/ +static inline void lctrExecAction(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t event) +{ + if (lctrSlvCisEstActionTbl[pCisCtx->estState][event]) + { + lctrSlvCisEstActionTbl[pCisCtx->estState][event](pCtx, pCisCtx); + } + + pCisCtx->estState = lctrSlvCisEstNextStateTbl[pCisCtx->estState][event]; +} + +/*************************************************************************************************/ +/*! + * \brief Get remapped event. This function also update the CIS handle for the LLCP. + * + * \param event Subsystem event. + * \param pCtx Connection context. + * + * \return Procedure event ID. + */ +/*************************************************************************************************/ +static uint8_t lctrRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + /*** Peer messages ***/ + + case LCTR_CONN_MSG_RX_LLCP: + switch (lctrDataPdu.opcode) + { + case LL_PDU_CIS_REQ: + { + lctrCigCtx_t *pCigCtx; + if ((pCigCtx = lctrFindCigById(lctrDataPdu.pld.cisReq.cigId)) == NULL) + { + if ((pCigCtx = lctrAllocCigCtx(lctrDataPdu.pld.cisReq.cigId)) == NULL) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_LIMIT_REACHED, TRUE); + LL_TRACE_WARN0("Not able to allocate a CIG context"); + break; + } + } + + lctrCisCtx_t *pCisCtx ; + if ((pCisCtx = lctrAllocCisCtx(pCigCtx)) == NULL) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_LIMIT_REACHED, TRUE); + LL_TRACE_WARN0("Not able to allocate a CIS context"); + break; + } + pCisCtx->aclHandle = LCTR_GET_CONN_HANDLE(pCtx); /* Save the ACL handle. */ + pCisCtx->role = LL_ROLE_SLAVE; + pCtx->llcpCisHandle = pCisCtx->cisHandle; /* Update LLCP CIS handle for connection context from peer. */ + pCtx->checkCisTerm = lctrCheckForCisLinkTerm; + lctrCheckCisEstCisFn = lctrCheckIsCisEstCis; + return LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ; + } + + case LL_PDU_CIS_IND: + return LCTR_CIS_SLV_EST_EVENT_PERR_CIS_IND; + + case LL_PDU_REJECT_EXT_IND: + { + if (lctrDataPdu.pld.rejInd.opcode == LL_PDU_CIS_RSP) + { + return LCTR_CIS_SLV_EST_EVENT_PEER_REJECT; + } + break; + } + + default: + break; + } + break; + + /*** Host messages ***/ + case LCTR_CONN_MSG_API_CIS_REQ_REJECT: + return LCTR_CIS_SLV_EST_EVENT_HOST_REQ_REJECT; + + case LCTR_CONN_MSG_API_CIS_REQ_ACCEPT: + return LCTR_CIS_SLV_EST_EVENT_HOST_REQ_ACCEPT; + + /*** Internal messages ***/ + case LCTR_CONN_LLCP_START_PENDING: + if (pCtx->llcpPendMask & (1 << LCTR_PROC_CIS_EST_PEER)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_CIS_EST_PEER); + return LCTR_CIS_SLV_EST_EVENT_INT_PEER_CIS_REQ; + } + break; + default: + break; + } + return LCTR_CIS_SLV_EST_EVENT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Resolve procedure collision. + * + * \param event Subsystem event. + * \param pCisCtx CIS context. + * \param pCtx Connection context. + */ +/*************************************************************************************************/ +static void lctrResolveCollision(lctrConnCtx_t *pCtx, lctrCisCtx_t *pCisCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ: + if ((pCtx->llcpActiveProc == LCTR_PROC_CMN_CH_MAP_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_PHY_UPD) || + (pCtx->llcpActiveProc == LCTR_PROC_CONN_PARAM)) + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_DIFFERENT_TRANSACTION_COLLISION, TRUE); + } + else + { + lctrCisStorePeerCisReq(pCtx, pCisCtx); + pCtx->llcpPendMask |= 1 << LCTR_PROC_CIS_EST_PEER; + LL_TRACE_INFO2("Pending CIS_REQ=%u procedure: activeProc=%u", LCTR_PROC_CIS_EST_PEER, pCtx->llcpActiveProc); + } + break; + + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Check if active procedure can be overridden with phy update procedure. + * + * \param pCtx Connection context. + * \param event Subsystem event. + * + * This routine will pend the active procedure and allow the phy update procedure to + * override it. + */ +/*************************************************************************************************/ +static void lctrCheckProcOverride(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CIS_SLV_EST_EVENT_PEER_CIS_REQ: + /* Only the procedure without instant fields can be overridden. */ + switch (pCtx->llcpActiveProc) + { + case LCTR_PROC_CMN_VER_EXCH: + case LCTR_PROC_CMN_FEAT_EXCH: + case LCTR_PROC_CMN_DATA_LEN_UPD: + case LCTR_PROC_CMN_REQ_PEER_SCA: + pCtx->llcpPendMask |= 1 << pCtx->llcpActiveProc; + pCtx->llcpActiveProc = LCTR_PROC_CIS_EST; + pCtx->llcpIsOverridden = TRUE; + break; + + default: + break; + } + break; + + default: + break; + } +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Execute slave CIS establishment LLCP state machine. + * + * \param pCtx Connection context. + * \param event State machine event. + * + * \return TRUE if the event is handled by this state machine, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrSlvLlcpExecuteCisEstSm(lctrConnCtx_t *pCtx, uint8_t event) +{ + if ((event = lctrRemapEvent(pCtx, event)) == LCTR_CIS_SLV_EST_EVENT_INVALID) + { + return FALSE; + } + + lctrCisCtx_t *pCisCtx = lctrFindCisByHandle(pCtx->llcpCisHandle); + WSF_ASSERT(pCisCtx != NULL) + + switch (pCtx->llcpState) + { + case LCTR_LLCP_STATE_IDLE: + LL_TRACE_INFO3("lctrSlvLlcpExecuteCisEstSm: handle=%u, llcpState=IDLE, estState=%u, event=%u", LCTR_GET_CONN_HANDLE(pCtx), pCisCtx->estState, event); + + lctrExecAction(pCtx, pCisCtx, event); + + if (pCisCtx->estState != LCTR_CIS_SLV_EST_STATE_IDLE) + { + pCtx->llcpState = LCTR_LLCP_STATE_BUSY; + pCtx->llcpActiveProc = LCTR_PROC_CIS_EST; + } + break; + + case LCTR_LLCP_STATE_BUSY: + LL_TRACE_INFO3("lctrSlvLlcpExecuteCisEstSm: handle=%u, llcpState=BUSY, estState=%u, event=%u", LCTR_GET_CONN_HANDLE(pCtx), pCisCtx->estState, event); + + lctrCheckProcOverride(pCtx, event); + + if (pCtx->llcpActiveProc == LCTR_PROC_CIS_EST) + { + lctrExecAction(pCtx, pCisCtx, event); + + if (pCisCtx->estState == LCTR_CIS_SLV_EST_STATE_IDLE) + { + lctrCisStopLlcpTimer(pCtx, pCisCtx); + pCtx->llcpState = LCTR_LLCP_STATE_IDLE; + pCtx->llcpActiveProc = LCTR_PROC_INVALID; + + lctrStartPendingLlcp(pCtx); + } + } + else + { + lctrResolveCollision(pCtx, pCisCtx, event); + } + + break; + + default: + break; + } + + return TRUE; +} + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn.c index f697a267fe6..54baacaf8f0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LLCP state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LLCP state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -151,8 +152,6 @@ const lctrLlcpEh_t lctrCmnProcTbl[LCTR_PROC_CMN_TOTAL][LCTR_PROC_CMN_ACT_TOTAL] * \param pCtx Connection context. * \param proc Procedure ID. * \param act Action ID. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t proc, uint8_t act) @@ -556,8 +555,6 @@ static bool_t lctrFeatureAvail(lctrConnCtx_t *pCtx, uint8_t proc, uint8_t event) * * \param pCtx Connection context. * \param status Status. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyHostReadRemoteFeatCnf(lctrConnCtx_t *pCtx, uint8_t status) @@ -591,8 +588,6 @@ static void lctrNotifyHostReadRemoteFeatCnf(lctrConnCtx_t *pCtx, uint8_t status) * * \param pCtx Connection context. * \param proc Completed procedure. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyHostSuccess(lctrConnCtx_t *pCtx, uint8_t proc) @@ -629,8 +624,6 @@ static void lctrNotifyHostSuccess(lctrConnCtx_t *pCtx, uint8_t proc) * * \param pCtx Connection context. * \param proc Complete procedure. - * - * \return None. */ /*************************************************************************************************/ static void lctrNotifyHostReject(lctrConnCtx_t *pCtx, uint8_t proc) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_master.c index 99f77164818..0f7f8ab60d5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller master connection state machine implementation file. + * \file + * + * \brief Link layer controller master connection state machine implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -74,8 +75,6 @@ LctrLlcpHdlr_t lctrMstLlcpSmTbl[LCTR_LLCP_SM_TOTAL]; * \brief Action indirection for start connection update. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartConnUpd(lctrConnCtx_t *pCtx) @@ -109,8 +108,6 @@ static void lctrActStartConnUpd(lctrConnCtx_t *pCtx) * \brief Action indirection for received host connection update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostConnUpd(lctrConnCtx_t *pCtx) @@ -125,8 +122,6 @@ static void lctrActHostConnUpd(lctrConnCtx_t *pCtx) * \brief Action indirection for received host connection update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerConnParam(lctrConnCtx_t *pCtx) @@ -141,8 +136,6 @@ static void lctrActPeerConnParam(lctrConnCtx_t *pCtx) * \brief Action indirection for start connection parameter command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartConnParam(lctrConnCtx_t *pCtx) @@ -156,8 +149,6 @@ static void lctrActStartConnParam(lctrConnCtx_t *pCtx) * \brief Action indirection for host reply command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostReply(lctrConnCtx_t *pCtx) @@ -174,8 +165,6 @@ static void lctrActHostReply(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_CONN_PARAM_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerConnParamRsp(lctrConnCtx_t *pCtx) @@ -191,8 +180,6 @@ static void lctrActPeerConnParamRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for skipping peer LL_CONN_PARAM_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActSkipConnParamRsp(lctrConnCtx_t *pCtx) @@ -206,8 +193,6 @@ static void lctrActSkipConnParamRsp(lctrConnCtx_t *pCtx) * \brief Notify host of connection update with disallowed status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActConnUpdDisallow(lctrConnCtx_t *pCtx) @@ -221,8 +206,6 @@ static void lctrActConnUpdDisallow(lctrConnCtx_t *pCtx) * \brief Send peer LL_REJECT_IND due to pending operation. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActRejectCollision(lctrConnCtx_t *pCtx) @@ -236,8 +219,6 @@ static void lctrActRejectCollision(lctrConnCtx_t *pCtx) * \brief Notify host of local rejected connection parameter procedure. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActLocalRejectConnParam(lctrConnCtx_t *pCtx) @@ -379,8 +360,6 @@ static const uint8_t lctrMstConnUpdNextStateTbl[LCTR_CU_STATE_TOTAL][LCTR_CU_EVE * * \param pCtx Connection context. * \param event Event ID. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t event) @@ -499,8 +478,6 @@ static uint8_t lctrMstConnUpdRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) * * \param event Subsystem event. * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) @@ -538,8 +515,6 @@ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) * \param pCtx Connection context. * \param event Subsystem event. * - * \return None. - * * This routine will pend the active procedure and allow the connection update procedure to * override it. */ @@ -642,8 +617,6 @@ bool_t lctrMstLlcpExecuteConnUpdSm(lctrConnCtx_t *pCtx, uint8_t event) * * \param pCtx Connection context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrMstLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) @@ -660,6 +633,7 @@ void lctrMstLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) return; } break; + default: break; } @@ -670,6 +644,7 @@ void lctrMstLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) !(lctrMstLlcpSmTbl[LCTR_LLCP_SM_PHY_UPD] && lctrMstLlcpSmTbl[LCTR_LLCP_SM_PHY_UPD](pCtx, event)) && !(lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_EST] && lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_EST](pCtx, event)) && !(lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM] && lctrMstLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM](pCtx, event)) && + !(lctrMstLlcpSmTbl[LCTR_LLCP_SM_PC] && lctrMstLlcpSmTbl[LCTR_LLCP_SM_PC](pCtx, event)) && !(lctrMstLlcpSmTbl[LCTR_LLCP_SM_CMN] && lctrMstLlcpSmTbl[LCTR_LLCP_SM_CMN](pCtx, event))) { lctrLlcpStatelessEventHandler(pCtx, event); diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_slave.c index 328dae2065a..4d0e7bbc6c5 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave connection state machine implementation file. + * \file + * + * \brief Link layer controller slave connection state machine implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -68,8 +69,6 @@ LctrLlcpHdlr_t lctrSlvLlcpSmTbl[LCTR_LLCP_SM_TOTAL]; * \brief Action indirection for start connection update. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartConnUpd(lctrConnCtx_t *pCtx) @@ -92,8 +91,6 @@ static void lctrActStartConnUpd(lctrConnCtx_t *pCtx) * \brief Action indirection for received host connection update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostConnUpd(lctrConnCtx_t *pCtx) @@ -108,8 +105,6 @@ static void lctrActHostConnUpd(lctrConnCtx_t *pCtx) * \brief Action indirection for received host connection update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerConnParam(lctrConnCtx_t *pCtx) @@ -125,8 +120,6 @@ static void lctrActPeerConnParam(lctrConnCtx_t *pCtx) * \brief Action indirection for received host connection update command with collision. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerConnParamWithCollision(lctrConnCtx_t *pCtx) @@ -139,8 +132,6 @@ static void lctrActPeerConnParamWithCollision(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_CONN_IND. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerConnInd(lctrConnCtx_t *pCtx) @@ -154,8 +145,6 @@ static void lctrActPeerConnInd(lctrConnCtx_t *pCtx) * \brief Action indirection for host reply command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostReply(lctrConnCtx_t *pCtx) @@ -170,8 +159,6 @@ static void lctrActHostReply(lctrConnCtx_t *pCtx) * \brief Action indirection for host negative reply command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActHostNegReply(lctrConnCtx_t *pCtx) @@ -186,8 +173,6 @@ void lctrActHostNegReply(lctrConnCtx_t *pCtx) * \brief Notify host of peer rejected connection parameter procedure. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActPeerRejectConnParam(lctrConnCtx_t *pCtx) @@ -215,8 +200,6 @@ void lctrActPeerRejectConnParam(lctrConnCtx_t *pCtx) * \brief Notify host of connection update with success status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActNotifyHostConnUpdSuccess(lctrConnCtx_t *pCtx) @@ -233,8 +216,6 @@ void lctrActNotifyHostConnUpdSuccess(lctrConnCtx_t *pCtx) * \brief Notify host connection completed due to colliding connection parameter from peer. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActNotifyHostColliding(lctrConnCtx_t *pCtx) @@ -248,8 +229,6 @@ static void lctrActNotifyHostColliding(lctrConnCtx_t *pCtx) * \brief Notify host of connection update with disallowed status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActConnUpdDisallow(lctrConnCtx_t *pCtx) @@ -263,8 +242,6 @@ static void lctrActConnUpdDisallow(lctrConnCtx_t *pCtx) * \brief Send peer LL_REJECT_IND due to pending operation. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActRejectCollision(lctrConnCtx_t *pCtx) @@ -373,8 +350,6 @@ static const uint8_t lctrSlvConnUpdNextStateTbl[LCTR_CU_STATE_TOTAL][LCTR_CU_EVE * * \param pCtx Connection context. * \param event Event ID. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t event) @@ -486,8 +461,6 @@ static uint8_t lctrSlvConnUpdRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) * * \param event Subsystem event. * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) @@ -531,8 +504,6 @@ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) * \param pCtx Connection context. * \param event Subsystem event. * - * \return None. - * * This routine will pend the active procedure and allow the connection update procedure to * override it. */ @@ -638,8 +609,6 @@ bool_t lctrSlvLlcpExecuteConnUpdSm(lctrConnCtx_t *pCtx, uint8_t event) * * \param pCtx Connection context. * \param event Control event. - * - * \return None. */ /*************************************************************************************************/ void lctrLlcpStatelessEventHandler(lctrConnCtx_t *pCtx, uint8_t event) @@ -681,8 +650,6 @@ void lctrLlcpStatelessEventHandler(lctrConnCtx_t *pCtx, uint8_t event) * * \param pCtx Connection context. * \param event State machine event. - * - * \return None. */ /*************************************************************************************************/ void lctrSlvLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) @@ -698,6 +665,7 @@ void lctrSlvLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) return; } break; + default: break; } @@ -708,7 +676,8 @@ void lctrSlvLlcpExecuteSm(lctrConnCtx_t *pCtx, uint8_t event) !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_PHY_UPD] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_PHY_UPD](pCtx, event)) && !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_EST] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_EST](pCtx, event)) && !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CIS_TERM](pCtx, event)) && - !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CMN] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CMN](pCtx, event))) + !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_PC] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_PC](pCtx, event)) && + !(lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CMN] && lctrSlvLlcpSmTbl[LCTR_LLCP_SM_CMN](pCtx, event)) ) { lctrLlcpStatelessEventHandler(pCtx, event); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_master.c index 0c2f6e370b7..f61dbc80a29 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master encryption connection state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master encryption connection state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -74,8 +75,6 @@ enum * \brief Notify host of encryption change with disallowed status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActEncChangeDisallow(lctrConnCtx_t *pCtx) @@ -89,8 +88,6 @@ static void lctrActEncChangeDisallow(lctrConnCtx_t *pCtx) * \brief Action indirection for received host start encryption command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartEnc(lctrConnCtx_t *pCtx) @@ -104,8 +101,6 @@ static void lctrActStartEnc(lctrConnCtx_t *pCtx) * \brief Action Tx data queue flushed on encryption start. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActTxFlushedOnStart(lctrConnCtx_t *pCtx) @@ -121,8 +116,6 @@ static void lctrActTxFlushedOnStart(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_ENC_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerEncRsp(lctrConnCtx_t *pCtx) @@ -141,8 +134,6 @@ static void lctrActPeerEncRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_START_ENC_REQ. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerStartEncReq(lctrConnCtx_t *pCtx) @@ -158,8 +149,6 @@ static void lctrActPeerStartEncReq(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_START_ENC_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerStartEncRsp(lctrConnCtx_t *pCtx) @@ -177,8 +166,6 @@ static void lctrActPeerStartEncRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for received host refresh key. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActRefreshEncKey(lctrConnCtx_t *pCtx) @@ -194,8 +181,6 @@ static void lctrActRefreshEncKey(lctrConnCtx_t *pCtx) * \brief Action Tx data queue flushed on encryption restart. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActTxFlushedOnRestart(lctrConnCtx_t *pCtx) @@ -209,8 +194,6 @@ static void lctrActTxFlushedOnRestart(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_PAUSE_ENC_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPauseEncRsp(lctrConnCtx_t *pCtx) @@ -228,8 +211,6 @@ static void lctrActPeerPauseEncRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_REJECT_IND. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerEncReject(lctrConnCtx_t *pCtx) @@ -546,10 +527,10 @@ bool_t lctrMstExecuteEncryptSm(lctrConnCtx_t *pCtx, uint8_t event) { if (pCtx->pauseRxData == TRUE) /* During encryption start or encryption pause. */ { - switch(event) + switch (event) { case LCTR_CONN_MSG_RX_LLCP: - switch(lctrDataPdu.opcode) + switch (lctrDataPdu.opcode) { /* Allowed PDUs. */ case LL_PDU_TERMINATE_IND: diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_slave.c index c9d3df3ff26..e60fd8b1c25 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave encryption connection state machine implementation file. + * \file + * + * \brief Link layer controller slave encryption connection state machine implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -89,8 +90,6 @@ enum * \brief Action indirection for received peer LL_ENC_REQ. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerEncReq(lctrConnCtx_t *pCtx) @@ -105,8 +104,6 @@ static void lctrActPeerEncReq(lctrConnCtx_t *pCtx) * \brief Action Tx data queue flushed after a start encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActTxFlushedOnStart(lctrConnCtx_t *pCtx) @@ -126,8 +123,6 @@ static void lctrActTxFlushedOnStart(lctrConnCtx_t *pCtx) * \brief Action indirection for received host LTK request reply HCI command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostLtkReply(lctrConnCtx_t *pCtx) @@ -146,8 +141,6 @@ static void lctrActHostLtkReply(lctrConnCtx_t *pCtx) * \brief Action indirection for received host LTK request negative reply HCI command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostLtkNegReply(lctrConnCtx_t *pCtx) @@ -177,8 +170,6 @@ static void lctrActHostLtkNegReply(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_START_ENC_RSP. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerStartEncRsp(lctrConnCtx_t *pCtx) @@ -198,8 +189,6 @@ static void lctrActPeerStartEncRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer LL_PAUSE_ENC_REQ. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPauseEncReq(lctrConnCtx_t *pCtx) @@ -217,8 +206,6 @@ static void lctrActPeerPauseEncReq(lctrConnCtx_t *pCtx) * \brief Action Tx data queue flushed after a restart encryption. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActTxFlushedOnRestart(lctrConnCtx_t *pCtx) @@ -432,8 +419,6 @@ static uint8_t lctrSlvRemapEncryptEvent(lctrConnCtx_t *pCtx, uint8_t event) * \param pCtx Connection context. * \param event Subsystem event. * - * \return None. - * * This routine will pend the active procedure and allow the encryption procedure to override it. */ /*************************************************************************************************/ @@ -553,10 +538,10 @@ bool_t lctrSlvExecuteEncryptSm(lctrConnCtx_t *pCtx, uint8_t event) { if (pCtx->pauseRxData == TRUE) /* During encryption start or encryption pause. */ { - switch(event) + switch (event) { case LCTR_CONN_MSG_RX_LLCP: - switch(lctrDataPdu.opcode) + switch (lctrDataPdu.opcode) { /* Allowed PDUs. */ case LL_PDU_TERMINATE_IND: diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_master_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_master_phy.c index 376caedc3bc..a34367b94b7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_master_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_master_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer controller master PHY update state machine implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer controller master PHY update state machine implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -106,8 +107,6 @@ static bool_t lctrPreferenceIsSymmetric(uint8_t peerTxPhys, uint8_t peerRxPhys) * \param rxPhys Preferred receiver PHYs. * \param peerTxPhys Peer's preferred transmitter PHYs. * \param peerRxPhys Peer'sreferred receiver PHYs. - * - * \return None. */ /*************************************************************************************************/ static void lctrSendPhyUpdate(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhys, uint8_t peerTxPhys, uint8_t peerRxPhys) @@ -164,8 +163,6 @@ static void lctrSendPhyUpdate(lctrConnCtx_t *pCtx, uint8_t txPhys, uint8_t rxPhy * \brief Action indirection for start PHY update. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartPhyUpdatePeer(lctrConnCtx_t *pCtx) @@ -193,8 +190,6 @@ static void lctrActStartPhyUpdatePeer(lctrConnCtx_t *pCtx) * \brief Action indirection for received host PHY update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostPhyUpdate(lctrConnCtx_t *pCtx) @@ -209,8 +204,6 @@ static void lctrActHostPhyUpdate(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer PHY request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPhyReq(lctrConnCtx_t *pCtx) @@ -224,8 +217,6 @@ static void lctrActPeerPhyReq(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer PHY response. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPhyRsp(lctrConnCtx_t *pCtx) @@ -239,8 +230,6 @@ static void lctrActPeerPhyRsp(lctrConnCtx_t *pCtx) * \brief Send peer LL_REJECT_IND due to pending operation. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActRejectCollision(lctrConnCtx_t *pCtx) @@ -254,8 +243,6 @@ static void lctrActRejectCollision(lctrConnCtx_t *pCtx) * \brief Notify host of PHY update with disallowed status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPhyUpdateDisallow(lctrConnCtx_t *pCtx) @@ -384,8 +371,6 @@ static const uint8_t lctrMstPhyUpdateNextStateTbl[LCTR_PU_STATE_TOTAL][LCTR_PU_E * * \param pCtx Connection context. * \param event Event ID. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t event) @@ -492,8 +477,6 @@ static uint8_t lctrRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) * * \param event Subsystem event. * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) @@ -534,8 +517,6 @@ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) * \param pCtx Connection context. * \param event Subsystem event. * - * \return None. - * * This routine will pend the active procedure and allow the phy update procedure to * override it. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_pc.c new file mode 100644 index 00000000000..2fbb9dbe317 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_pc.c @@ -0,0 +1,546 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Power control LLCP state machine implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_int_conn.h" +#include "lctr_int_conn_slave.h" +#include "lmgr_api.h" +#include "lctr_int_pc.h" +#include "util/bstream.h" +#include "wsf_trace.h" + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Power control LLCP types. */ +enum +{ + LCTR_PC_PROC_IND, /*!< Power Indication process. */ + LCTR_PC_PROC_CTRL, /*!< Power control process. */ + + LCTR_PC_PROC_TOTAL /*!< Total power control procedures. */ +}; + +/*! \brief Common LLCP actions. */ +enum +{ + LCTR_PROC_CMN_ACT_API_PARAM, /*!< Store host API parameter action. */ + LCTR_PROC_CMN_ACT_SEND_REQ, /*!< Send request action. */ + LCTR_PROC_CMN_ACT_RECV_REQ, /*!< Receive request action. */ + LCTR_PROC_CMN_ACT_SEND_RSP, /*!< Send response action. */ + LCTR_PROC_CMN_ACT_RECV_RSP, /*!< Receive response action. */ + LCTR_PROC_CMN_ACT_TOTAL /*!< Total common procedure actions. */ +}; + +/*! \brief Common LLCP events. */ +enum +{ + LCTR_PROC_CMN_EVT_HOST_START, /*!< Host initiated start procedure event. */ + LCTR_PROC_CMN_EVT_INT_START, /*!< LL initiated start procedure event. */ + LCTR_PROC_CMN_EVT_INT_INCOMP, /*!< Complete an interrupted procedure event. */ + LCTR_PROC_CMN_EVT_RECV_IND, /*!< Receive indication event. */ + LCTR_PROC_CMN_EVT_RECV_REQ, /*!< Receive request event. */ + LCTR_PROC_CMN_EVT_RECV_RSP, /*!< Receive response event. */ + LCTR_PROC_CMN_EVT_PROC_COMP, /*!< Procedure completed event. */ + LCTR_PROC_CMN_EVT_REJECT, /*!< Procedure rejected event. */ + LCTR_PROC_CMN_EVT_TOTAL, /*!< Total common procedure events. */ + LCTR_PROC_CMN_EVT_INVALID = 0xFF /*!< Invalid event. */ +}; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Common procedure state machine action table. */ +const lctrLlcpEh_t lctrPclProcTbl[LCTR_PC_PROC_TOTAL][LCTR_PROC_CMN_ACT_TOTAL] = +{ + /* LCTR_PROC_PWR_IND */ + { + NULL, /* LCTR_PROC_CMN_ACT_API_PARAM */ + NULL, /* LCTR_PROC_CMN_ACT_SEND_REQ */ + lctrStorePeerPowerInd, /* LCTR_PROC_CMN_ACT_RECV_REQ */ + lctrSendPeerPowerRsp, /* LCTR_PROC_CMN_ACT_SEND_RSP */ + NULL /* LCTR_PROC_CMN_ACT_RECV_RSP */ + }, + /* LCTR_PROC_PWR_CTRL */ + { + lctrStorePowerControlAction, /* LCTR_PROC_CMN_ACT_API_PARAM */ + lctrSendPeerPowerControlReq, /* LCTR_PROC_CMN_ACT_SEND_REQ */ + lctrStorePeerPowerControlReq, /* LCTR_PROC_CMN_ACT_RECV_REQ */ + lctrSendPeerPowerControlRsp, /* LCTR_PROC_CMN_ACT_SEND_RSP */ + lctrStorePeerPowerControlRsp /* LCTR_PROC_CMN_ACT_RECV_RSP */ + } +}; + +/*************************************************************************************************/ +/*! + * \brief Get power control state machine index from process ID + * + * \param proc Process ID. + * + * \return Index of power control state machine. + */ +/*************************************************************************************************/ +static uint8_t lctrGetPclProcSmIndex(uint8_t proc) +{ + if (proc == LCTR_PROC_PWR_IND) + { + return LCTR_PC_PROC_IND; + } + else if (proc == LCTR_PROC_PWR_CTRL) + { + return LCTR_PC_PROC_CTRL; + } + else + { + LL_TRACE_ERR1("lctrGetPclProcSmIndex, invalid proc=%d", proc); + return LCTR_PROC_INVALID; + } +} + +/*************************************************************************************************/ +/*! + * \brief Execute action function. + * + * \param pCtx Connection context. + * \param proc Procedure ID. + * \param act Action ID. + */ +/*************************************************************************************************/ +static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t proc, uint8_t act) +{ + uint8_t pclProc = lctrGetPclProcSmIndex(proc); + + if (lctrPclProcTbl[pclProc][act]) + { + lctrPclProcTbl[pclProc][act](pCtx); + } +} + +/*************************************************************************************************/ +/*! + * \brief Get power control LLCP procedure ID. + * + * \param pCtx Connection context. + * \param event Event. + * + * \return LLCP procedure event ID. + */ +/*************************************************************************************************/ +static uint8_t lctrGetPclProcId(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CONN_MSG_API_PWR_CTRL_REQ: + return LCTR_PROC_PWR_CTRL; + + case LCTR_CONN_MSG_RX_LLCP: + switch (lctrDataPdu.opcode) + { + case LL_PDU_PWR_CHNG_IND: + return LCTR_PROC_PWR_IND; + + case LL_PDU_PWR_CTRL_REQ: + case LL_PDU_PWR_CTRL_RSP: + return LCTR_PROC_PWR_CTRL; + + case LL_PDU_REJECT_IND: + case LL_PDU_REJECT_EXT_IND: + return pCtx->llcpActiveProc; + + default: + break; + } + + break; + + case LCTR_CONN_LLCP_START_PENDING: + if (pCtx->llcpPendMask & (1 << LCTR_PROC_PWR_IND)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_PWR_IND); + return LCTR_PROC_PWR_IND; + } + if (pCtx->llcpPendMask & (1 << LCTR_PROC_PWR_CTRL)) + { + pCtx->llcpPendMask &= ~(1 << LCTR_PROC_PWR_CTRL); + return LCTR_PROC_PWR_CTRL; + } + break; + + default: + break; + } + + return LCTR_PROC_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Get remapped common LLCP procedure event. + * + * \param pCtx Connection context. + * \param event Subsystem event. + * + * \return Common LLCP procedure action ID. + * + * This routine remaps events for the common LLCP procedure state machine for optimized + * compressed state tables. + */ +/*************************************************************************************************/ +static uint8_t lctrRemapCmnProcEvent(lctrConnCtx_t *pCtx, uint8_t event) +{ + switch (event) + { + case LCTR_CONN_MSG_API_PWR_CTRL_REQ: + return LCTR_PROC_CMN_EVT_HOST_START; + + case LCTR_CONN_MSG_RX_LLCP_UNKNOWN: + return LCTR_PROC_CMN_EVT_RECV_REQ; + + case LCTR_CONN_MSG_RX_LLCP: + switch (lctrDataPdu.opcode) + { + case LL_PDU_PWR_CTRL_REQ: + return LCTR_PROC_CMN_EVT_RECV_REQ; + + case LL_PDU_PWR_CHNG_IND: + return LCTR_PROC_CMN_EVT_RECV_IND; + + case LL_PDU_PWR_CTRL_RSP: + return LCTR_PROC_CMN_EVT_RECV_RSP; + + case LL_PDU_UNKNOWN_RSP: + case LL_PDU_REJECT_IND: + case LL_PDU_REJECT_EXT_IND: + return LCTR_PROC_CMN_EVT_REJECT; + + default: + return LCTR_PROC_CMN_EVT_INVALID; + } + + case LCTR_CONN_LLCP_START_PENDING: + if (pCtx->llcpIncompMask) + { + return LCTR_PROC_CMN_EVT_INT_INCOMP; + } + else + { + return LCTR_PROC_CMN_EVT_INT_START; + } + + default: + break; + } + + return LCTR_PROC_CMN_EVT_INVALID; +} + +/*************************************************************************************************/ +/*! + * \brief Check for feature availability. + * + * \param pCtx Connection context. + * \param proc Requesting procedure. + * \param event Event. + * + * \return TRUE if available, FALSE otherwise. + */ +/*************************************************************************************************/ +static bool_t lctrFeatureAvail(lctrConnCtx_t *pCtx, uint8_t proc, uint8_t event) +{ + bool_t result = TRUE; + + switch (proc) + { + case LCTR_PROC_PWR_IND: + if ((lmgrCb.features & LL_FEAT_POWER_CHANGE_IND) == 0) + { + LL_TRACE_WARN1("Requested LCTR_PROC_PWR_IND not available, FeatSet=0x%08x", lmgrCb.features); + result = FALSE; + } + break; + case LCTR_PROC_PWR_CTRL: + if ((lmgrCb.features & LL_FEAT_POWER_CONTROL_REQUEST) == 0) + { + LL_TRACE_WARN1("Requested LCTR_PROC_PWR_CTRL not available, FeatSet=0x%08x", lmgrCb.features); + result = FALSE; + } + break; + default: + break; + } + + return result; +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of successful procedure. + * + * \param pCtx Connection context. + * \param proc Completed procedure. + */ +/*************************************************************************************************/ +static void lctrNotifyHostSuccess(lctrConnCtx_t *pCtx, uint8_t proc) +{ + if ((pCtx->llcpNotifyMask & (1 << proc)) == 0) + { + return; + } + + pCtx->llcpNotifyMask &= ~(1 << proc); + + switch (proc) + { + case LCTR_PROC_PWR_CTRL: + if (pCtx->readRemoteTxPower) + { + lctrNotifyPowerReportInd(pCtx, LL_POWER_REPORT_REASON_READ_REMOTE, + pCtx->reqPhy, pCtx->peerTxPower, pCtx->peerPwrLimits, + pCtx->delta); + pCtx->readRemoteTxPower = FALSE; + } + break; + default: + break; + } +} + +/*************************************************************************************************/ +/*! + * \brief Notify host of failed procedure. + * + * \param pCtx Connection context. + * \param proc Complete procedure. + */ +/*************************************************************************************************/ +static void lctrNotifyHostReject(lctrConnCtx_t *pCtx, uint8_t proc) +{ + if ((pCtx->llcpNotifyMask & (1 << proc)) == 0) + { + return; + } + + pCtx->llcpNotifyMask &= ~(1 << proc); +} + +/*************************************************************************************************/ +/*! + * \brief Execute common LLCP state machine. + * + * \param pCtx Connection context. + * \param event State machine event. + * + * \return TRUE if handled by this SM, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lctrLlcpExecutePclSm(lctrConnCtx_t *pCtx, uint8_t event) +{ + uint8_t proc; + uint8_t llEvent = event; + + if ((event = lctrRemapCmnProcEvent(pCtx, event)) == LCTR_PROC_CMN_EVT_INVALID) + { + return FALSE; + } + + if ((proc = lctrGetPclProcId(pCtx, llEvent)) == LCTR_PROC_INVALID) + { + return FALSE; + } + + switch (pCtx->llcpState) + { + case LCTR_LLCP_STATE_IDLE: + LL_TRACE_INFO3("lctrLlcpExecutePclSm: handle=%u, proc=%u, state=IDLE, event=%u", LCTR_GET_CONN_HANDLE(pCtx), proc, event); + + switch (event) + { + case LCTR_PROC_CMN_EVT_HOST_START: + pCtx->llcpNotifyMask |= 1 << proc; + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_API_PARAM); + /* Fallthrough */ + case LCTR_PROC_CMN_EVT_INT_START: + if (lctrFeatureAvail(pCtx, proc, event)) + { + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_SEND_REQ); + lctrStartLlcpTimer(pCtx); + pCtx->llcpActiveProc = proc; + pCtx->cmnState = LCTR_CMN_STATE_BUSY; + pCtx->llcpState = LCTR_LLCP_STATE_BUSY; + } + else + { + lctrNotifyHostReject(pCtx, proc); + } + break; + + case LCTR_PROC_CMN_EVT_INT_INCOMP: + case LCTR_PROC_CMN_EVT_RECV_IND: + case LCTR_PROC_CMN_EVT_RECV_REQ: + if (lctrFeatureAvail(pCtx, proc, event)) + { + if (event != LCTR_PROC_CMN_EVT_INT_INCOMP) + { + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_RECV_REQ); + } + + if (lctrPclProcTbl[lctrGetPclProcSmIndex(proc)][LCTR_PROC_CMN_ACT_SEND_RSP]) + { + /* Procedure completes; no transition to BUSY. */ + lctrPclProcTbl[lctrGetPclProcSmIndex(proc)][LCTR_PROC_CMN_ACT_SEND_RSP](pCtx); + } + else + { + /* No response; procedure completes at CE instant. */ + pCtx->llcpActiveProc = proc; + pCtx->llcpInstantComp = FALSE; + pCtx->cmnState = LCTR_CMN_STATE_BUSY; + pCtx->llcpState = LCTR_LLCP_STATE_BUSY; + } + } + else + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE, FALSE); + } + break; + + case LCTR_PROC_CMN_EVT_RECV_RSP: + case LCTR_PROC_CMN_EVT_PROC_COMP: + case LCTR_PROC_CMN_EVT_REJECT: + default: + /* No action required. */ + break; + } + break; + + case LCTR_LLCP_STATE_BUSY: + LL_TRACE_INFO3("lctrLlcpExecutePclSm: handle=%u, proc=%u, state=BUSY, event=%u", LCTR_GET_CONN_HANDLE(pCtx), proc, event); + + switch (event) + { + case LCTR_PROC_CMN_EVT_HOST_START: + case LCTR_PROC_CMN_EVT_INT_START: + if (lctrFeatureAvail(pCtx, proc, event)) + { + if (event == LCTR_PROC_CMN_EVT_HOST_START) + { + pCtx->llcpNotifyMask |= 1 << proc; + } + + if (pCtx->llcpActiveProc != proc) + { + LL_TRACE_INFO1("Pending procedure in progress: activeProc=%u", pCtx->llcpActiveProc); + pCtx->llcpPendMask |= 1 << proc; + } + if (event == LCTR_PROC_CMN_EVT_HOST_START) + { + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_API_PARAM); + } + } + else + { + lctrNotifyHostReject(pCtx, proc); + } + break; + + case LCTR_PROC_CMN_EVT_RECV_IND: /* Completion from message */ + if (proc != pCtx->llcpActiveProc) + { + if (lctrFeatureAvail(pCtx, proc, event)) + { + LL_TRACE_WARN1("Procedure collision; pending incomplete request, activeProc=%u", pCtx->llcpActiveProc); + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_RECV_REQ); + pCtx->llcpIncompMask |= 1 << proc; + } + break; + } + /* Fallthrough */ + case LCTR_PROC_CMN_EVT_RECV_RSP: + if (proc == pCtx->llcpActiveProc) + { + /* Incoming procedure matches the active one. */ + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_RECV_RSP); + } + else if (pCtx->llcpPendMask & (1 << proc)) + { + /* Incoming procedure matches one of the pended one. */ + pCtx->llcpPendMask &= ~(1 << proc); + if (pCtx->llcpIsOverridden == TRUE) + { + pCtx->llcpIsOverridden = FALSE; + } + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_RECV_RSP); + lctrNotifyHostSuccess(pCtx, proc); + break; + } + else + { + LL_TRACE_ERR1("Unexpected response packet, expected llcpActiveProc=%u", pCtx->llcpActiveProc); + break; + } + /* Fallthrough */ + case LCTR_PROC_CMN_EVT_PROC_COMP: /* Completion from CE */ + case LCTR_PROC_CMN_EVT_REJECT: /* Failed completion */ + if (event == LCTR_PROC_CMN_EVT_REJECT) + { + lctrNotifyHostReject(pCtx, proc); + } + else + { + lctrNotifyHostSuccess(pCtx, proc); + } + + lctrStopLlcpTimer(pCtx); + + pCtx->llcpActiveProc = LCTR_PROC_INVALID; + pCtx->cmnState = LCTR_CMN_STATE_IDLE; + pCtx->llcpState = LCTR_LLCP_STATE_IDLE; + + lctrStartPendingLlcp(pCtx); + break; + + case LCTR_PROC_CMN_EVT_RECV_REQ: + LL_TRACE_WARN1("Procedure collision; pending incomplete request, activeProc=%u", pCtx->llcpActiveProc); + lctrExecAction(pCtx, proc, LCTR_PROC_CMN_ACT_RECV_REQ); + if (lctrFeatureAvail(pCtx, proc, event)) + { + lctrPclProcTbl[lctrGetPclProcSmIndex(proc)][LCTR_PROC_CMN_ACT_SEND_RSP](pCtx); + } + else + { + lctrSendRejectInd(pCtx, LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE, FALSE); + } + break; + + default: + /* No action. */ + break; + } + break; + + default: + break; + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_slave_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_slave_phy.c index 0febf049602..a4fc42e1068 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_slave_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lctr/lctr_sm_llcp_slave_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer controller slave PHY update state machine implementation file. + * \file + * + * \brief Link layer controller slave PHY update state machine implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -83,8 +84,6 @@ void lctrActFlushArq(lctrConnCtx_t *pCtx); * \brief Update effective data packet time after PHY update procedure completes and notify host. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrUpdateDataTime(lctrConnCtx_t *pCtx) @@ -97,26 +96,26 @@ static void lctrUpdateDataTime(lctrConnCtx_t *pCtx) switch (pCtx->bleData.chan.txPhy) { case BB_PHY_BLE_1M: - maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(pCtx->effDataPdu.maxTxLen), pCtx->effDataPdu.maxTxTime); + maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(pCtx->effDataPdu.maxTxLen, TRUE), pCtx->effDataPdu.maxTxTime); break; case BB_PHY_BLE_2M: - maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(pCtx->effDataPdu.maxTxLen), pCtx->effDataPdu.maxTxTime); + maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(pCtx->effDataPdu.maxTxLen, TRUE), pCtx->effDataPdu.maxTxTime); break; case BB_PHY_BLE_CODED: - maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->effDataPdu.maxTxLen), pCtx->effDataPdu.maxTxTime); + maxTxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->effDataPdu.maxTxLen, TRUE), pCtx->effDataPdu.maxTxTime); break; } switch (pCtx->bleData.chan.rxPhy) { case BB_PHY_BLE_1M: - maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(pCtx->effDataPdu.maxRxLen), pCtx->effDataPdu.maxRxTime); + maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_1M(pCtx->effDataPdu.maxRxLen, TRUE), pCtx->effDataPdu.maxRxTime); break; case BB_PHY_BLE_2M: - maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(pCtx->effDataPdu.maxRxLen), pCtx->effDataPdu.maxRxTime); + maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_2M(pCtx->effDataPdu.maxRxLen, TRUE), pCtx->effDataPdu.maxRxTime); break; case BB_PHY_BLE_CODED: - maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->effDataPdu.maxRxLen), pCtx->effDataPdu.maxRxTime); + maxRxTime = WSF_MIN(LL_DATA_LEN_TO_TIME_CODED_S8(pCtx->effDataPdu.maxRxLen, TRUE), pCtx->effDataPdu.maxRxTime); break; } @@ -163,8 +162,6 @@ static void lctrUpdateDataTime(lctrConnCtx_t *pCtx) * \brief Notify host of peer rejected PHY request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActPeerRejectPhyReq(lctrConnCtx_t *pCtx) @@ -197,8 +194,6 @@ void lctrActPeerRejectPhyReq(lctrConnCtx_t *pCtx) * \brief Notify host of connection update with no change. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActNotifyHostPhyUpdateNoChange(lctrConnCtx_t *pCtx) @@ -223,8 +218,6 @@ void lctrActNotifyHostPhyUpdateNoChange(lctrConnCtx_t *pCtx) * \brief Notify host of connection update with success status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActNotifyHostPhyUpdateSuccess(lctrConnCtx_t *pCtx) @@ -300,8 +293,6 @@ uint8_t lctrSuppPhys(void) * \param pTxPhys Preferred transmitter PHYs. * \param pRxPhys Preferred receiver PHYs. * \param peerPhys Peer preferred PHYs. - * - * \return None. */ /*************************************************************************************************/ static void lctrAdjustPhyPreference(lctrConnCtx_t *pCtx, uint8_t allPhys, uint8_t *pTxPhys, uint8_t *pRxPhys, uint8_t peerPhys) @@ -355,8 +346,6 @@ static void lctrAdjustPhyPreference(lctrConnCtx_t *pCtx, uint8_t allPhys, uint8_ * \brief Action indirection for start PHY update. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActStartPhyUpdate(lctrConnCtx_t *pCtx) @@ -400,8 +389,6 @@ void lctrActStartPhyUpdate(lctrConnCtx_t *pCtx) * \brief Action indirection for flushing ARQ. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ void lctrActFlushArq(lctrConnCtx_t *pCtx) @@ -419,8 +406,6 @@ void lctrActFlushArq(lctrConnCtx_t *pCtx) * \brief Action indirection for received host PHY update command. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActHostPhyUpdate(lctrConnCtx_t *pCtx) @@ -435,8 +420,6 @@ static void lctrActHostPhyUpdate(lctrConnCtx_t *pCtx) * \brief Action indirection for start PHY response. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActStartPhyRsp(lctrConnCtx_t *pCtx) @@ -460,8 +443,6 @@ static void lctrActStartPhyRsp(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer PHY request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPhyReq(lctrConnCtx_t *pCtx) @@ -475,8 +456,6 @@ static void lctrActPeerPhyReq(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer PHY update request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPhyUpdateReq(lctrConnCtx_t *pCtx) @@ -500,8 +479,6 @@ static void lctrActPeerPhyUpdateReq(lctrConnCtx_t *pCtx) * \brief Action indirection for received peer PHY request. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPeerPhyReqWithCollision(lctrConnCtx_t *pCtx) @@ -514,8 +491,6 @@ static void lctrActPeerPhyReqWithCollision(lctrConnCtx_t *pCtx) * \brief Notify host of PHY update with disallowed status. * * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrActPhyUpdateDisallow(lctrConnCtx_t *pCtx) @@ -652,8 +627,6 @@ static const uint8_t lctrSlvPhyUpdateNextStateTbl[LCTR_PU_STATE_TOTAL][LCTR_PU_E * * \param pCtx Connection context. * \param event Event ID. - * - * \return None. */ /*************************************************************************************************/ static inline void lctrExecAction(lctrConnCtx_t *pCtx, uint8_t event) @@ -760,8 +733,6 @@ static uint8_t lctrRemapEvent(lctrConnCtx_t *pCtx, uint8_t event) * * \param event Subsystem event. * \param pCtx Connection context. - * - * \return None. */ /*************************************************************************************************/ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) @@ -801,8 +772,6 @@ static void lctrResolveCollision(lctrConnCtx_t *pCtx, uint8_t event) * \param pCtx Connection context. * \param event Subsystem event. * - * \return None. - * * This routine will pend the active procedure and allow the phy update procedure to * override it. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd.c index 950b64cafc5..0f200898458 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -63,7 +64,7 @@ static uint8_t lhciUnpackSetEventMaskCmd(uint64_t *pEvtMsk, const uint8_t *pBuf) * \return Packet length. */ /*************************************************************************************************/ -static uint8_t lhciPackReadBufSizeEvt(uint8_t *pBuf, uint8_t status, uint16_t pktLen, uint16_t numPkts) +static uint8_t lhciPackReadBufSizeEvt(uint8_t *pBuf, uint8_t status, uint16_t pktLen, uint8_t numPkts) { const uint8_t len = LHCI_LEN_LE_READ_BUF_SIZE_EVT; @@ -121,7 +122,7 @@ static uint8_t lhciPackLocalSupCmds(uint8_t *pBuf, uint8_t status) memset(pBuf, 0, len); UINT8_TO_BSTREAM (pBuf, status); - memcpy(pBuf, LmgrReadHciSupCmd(), HCI_SUP_CMD_LEN); + memcpy(pBuf, lhciPersistCb.supCmds, HCI_SUP_CMD_LEN); return len; } @@ -152,8 +153,6 @@ static uint8_t lhciPackLocalSupFeat(uint8_t *pBuf, uint8_t status) * * \param pCmdHdr Command HCI header. * \param status Status value. - * - * \return None. */ /*************************************************************************************************/ void lhciSendCmdStatusEvt(LhciHdr_t *pCmdHdr, uint8_t status) @@ -176,8 +175,6 @@ void lhciSendCmdStatusEvt(LhciHdr_t *pCmdHdr, uint8_t status) * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciCommonSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) @@ -205,6 +202,7 @@ static void lhciCommonSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t case HCI_OPCODE_LE_WRITE_RF_PATH_COMP: case HCI_OPCODE_NOP: case HCI_OPCODE_LE_MODIFY_SLEEP_CLK_ACC: + case HCI_OPCODE_LE_SET_HOST_FEATURE: lhciPackCmdCompleteEvtStatus(pBuf, status); break; @@ -384,6 +382,10 @@ bool_t lhciCommonDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) case HCI_OPCODE_LE_READ_TX_POWER: paramLen = LHCI_LEN_LE_READ_SUP_TX_POWER; break; + case HCI_OPCODE_LE_SET_HOST_FEATURE: + status = LlSetHostFeatures(*pBuf, *(pBuf + 1)); + paramLen = LHCI_LEN_LE_SET_HOST_FEATURE; + break; case HCI_OPCODE_LE_WRITE_RF_PATH_COMP: { int16_t txPathComp; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master.c index f97fa3cd5a2..614875253f4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -59,8 +60,6 @@ static uint8_t lhciUnpackSetScanParamCmd(LlScanParam_t *pCmd, const uint8_t *pBu * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciMstScanSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master_ae.c index 6bf8d739199..382e6f1a4c6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -52,8 +53,6 @@ typedef struct * * \param pCmd Unpacked command structure. * \param pBuf Packed packet buffer. - * - * \return None. */ /*************************************************************************************************/ static void lhciUnpackSetExtScanParamCmd(lhciSetExtScanParamCmd_t *pCmd, const uint8_t *pBuf) @@ -86,8 +85,6 @@ static void lhciUnpackSetExtScanParamCmd(lhciSetExtScanParamCmd_t *pCmd, const u * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciMstAeSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) @@ -191,7 +188,17 @@ bool_t lhciMstExtScanDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) BSTREAM_TO_UINT16(cmd.skip, pBuf); BSTREAM_TO_UINT16(cmd.syncTimeOut, pBuf); pBuf++; /* Sync_CTE_Type (Unused) */ - status = LlPeriodicAdvCreateSync(&cmd); + + if (((cmd.options >> 1) & 0x01) && + ((lhciPersistCb.supCmds[40] & HCI_SUP_LE_SET_PER_ADV_RCV_ENABLE) == 0)) + { + status = LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH; + } + else + { + status = LlPeriodicAdvCreateSync(&cmd); + } + paramLen = LHCI_LEN_CMD_STATUS_EVT; break; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_priv.c index 7712a95c42d..27dcc6d82b9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -57,8 +58,6 @@ static uint8_t lhciPackReadResListSizeEvt(uint8_t *pBuf, uint8_t status, uint16_ * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciPrivAdvSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave.c index 8506dae9a9b..384854aa83a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -80,8 +81,6 @@ static uint8_t lhciUnpackSetAdvParamCmd(lhciSetAdvParamCmd_t *pCmd, const uint8_ * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciSlvAdvSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave_ae.c index c3a0ff86931..527853b7189 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,8 +37,6 @@ * \param status Status value. * \param paramLen Parameter length of the command status event. * \param handle Advertising handle. - * - * \return None. */ /*************************************************************************************************/ static void lhciSlvExtAdvSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t handle) @@ -238,7 +237,7 @@ bool_t lhciSlvExtAdvDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) uint8_t enable; BSTREAM_TO_UINT8(enable, pBuf); BSTREAM_TO_UINT8(handle, pBuf); - LlSetPeriodicAdvEnable(handle, enable); + LlSetPeriodicAdvEnable(enable, handle); /* Send command complete once LL finishes processing the command. */ return TRUE; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_master.c new file mode 100644 index 00000000000..ac7995b6c4e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_master.c @@ -0,0 +1,90 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "ll_api.h" +#include "util/bstream.h" +#include "wsf_math.h" +#include + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciMstBisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + + switch (pHdr->opCode) + { + case HCI_OPCODE_LE_BIG_CREATE_SYNC: + { + LlBigCreateSync_t param; + + BSTREAM_TO_UINT8(param.bigHandle, pBuf); + BSTREAM_TO_UINT16(param.syncHandle, pBuf); + BSTREAM_TO_UINT8(param.encrypt, pBuf); + memcpy(param.bcstCode, pBuf, sizeof(param.bcstCode)); + pBuf += 16; + BSTREAM_TO_UINT8(param.mse, pBuf); + BSTREAM_TO_UINT16(param.bigSyncTimeout, pBuf); + BSTREAM_TO_UINT8(param.numBis, pBuf); + memcpy(param.bis, pBuf, WSF_MIN(param.numBis, sizeof(param.bis))); + + status = LlBigCreateSync(¶m); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + case HCI_OPCODE_LE_BIG_TERMINATE_SYNC: + { + uint8_t bigHandle; + + BSTREAM_TO_UINT8(bigHandle, pBuf); + + LlBigTerminateSync(bigHandle); + break; + } + + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen == LHCI_LEN_CMD_STATUS_EVT) + { + lhciSendCmdStatusEvt(pHdr, status); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_slave.c new file mode 100644 index 00000000000..440d5b30282 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_bis_slave.c @@ -0,0 +1,121 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciSlvBisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + + switch (pHdr->opCode) + { + case HCI_OPCODE_LE_CREATE_BIG: + { + LlCreateBig_t param; + + BSTREAM_TO_UINT8 (param.bigHandle, pBuf); + BSTREAM_TO_UINT8 (param.advHandle, pBuf); + BSTREAM_TO_UINT8 (param.numBis, pBuf); + BSTREAM_TO_UINT24(param.sduInterUsec, pBuf); + BSTREAM_TO_UINT16(param.maxSdu, pBuf); + BSTREAM_TO_UINT16(param.mtlMs, pBuf); + BSTREAM_TO_UINT8 (param.rtn, pBuf); + BSTREAM_TO_UINT8 (param.phys, pBuf); + BSTREAM_TO_UINT8 (param.packing, pBuf); + BSTREAM_TO_UINT8 (param.framing, pBuf); + BSTREAM_TO_UINT8 (param.encrypt, pBuf); + memcpy(param.bcstCode, pBuf, sizeof(param.bcstCode)); + + status = LlCreateBig(¶m); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + case HCI_OPCODE_LE_CREATE_BIG_TEST: + { + LlCreateBigTest_t param; + + BSTREAM_TO_UINT8 (param.bigHandle, pBuf); + BSTREAM_TO_UINT8 (param.advHandle, pBuf); + BSTREAM_TO_UINT8 (param.numBis, pBuf); + BSTREAM_TO_UINT24(param.sduInterUsec, pBuf); + BSTREAM_TO_UINT16(param.isoInter, pBuf); + BSTREAM_TO_UINT8 (param.nse, pBuf); + BSTREAM_TO_UINT16(param.maxSdu, pBuf); + BSTREAM_TO_UINT16(param.maxPdu, pBuf); + BSTREAM_TO_UINT8 (param.phys, pBuf); + BSTREAM_TO_UINT8 (param.packing, pBuf); + BSTREAM_TO_UINT8 (param.framing, pBuf); + BSTREAM_TO_UINT8 (param.bn, pBuf); + BSTREAM_TO_UINT8 (param.irc, pBuf); + BSTREAM_TO_UINT8 (param.pto, pBuf); + BSTREAM_TO_UINT8 (param.encrypt, pBuf); + memcpy(param.bcstCode, pBuf, sizeof(param.bcstCode)); + + status = LlCreateBigTest(¶m); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + case HCI_OPCODE_LE_TERMINATE_BIG: + { + uint8_t bigHandle; + uint8_t reason; + + BSTREAM_TO_UINT8(bigHandle, pBuf); + BSTREAM_TO_UINT8(reason, pBuf); + + status = LlTerminateBig(bigHandle, reason); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen == LHCI_LEN_CMD_STATUS_EVT) + { + lhciSendCmdStatusEvt(pHdr, status); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_master.c new file mode 100644 index 00000000000..8126506cc00 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_master.c @@ -0,0 +1,308 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "ll_defs.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +uint8_t numCis; /*!< Number of CIS. */ +uint8_t cigID; /*!< Number of CIS. */ +uint16_t cisHandles[LL_MAX_CIS] = {0}; /*!< CIS Handle list. */ + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a set CIG parameters event. + * + * \param pBuf Packed packet buffer. + * \param status Status code. + * \param numHandles Number of cis handles. + * \param pCisHandles Handle numbers. + */ +/*************************************************************************************************/ +static void lhciPackSetCigParamsEvt(uint8_t *pBuf, uint8_t status, uint8_t numHandles, uint16_t *pCisHandles) +{ + UINT8_TO_BSTREAM (pBuf, status); + UINT8_TO_BSTREAM (pBuf, cigID); + UINT8_TO_BSTREAM (pBuf, numHandles); + + for (unsigned int i = 0; i < numHandles; i++) + { + UINT16_TO_BSTREAM (pBuf, pCisHandles[i]); + } + + return; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a remove CIG event. + * + * \param pBuf Packed packet buffer. + * \param status Status code. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackRemoveCigEvt(uint8_t *pBuf, uint8_t status) +{ + const uint8_t len = LHCI_LEN_LE_REMOVE_CIG; + + UINT8_TO_BSTREAM (pBuf, status); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Build and send a command complete event packet. + * + * \param pCmdHdr Command HCI header. + * \param status Status value. + * \param paramLen Parameter length of the command status event. + */ +/*************************************************************************************************/ +static void lhciCisMstSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) +{ + uint8_t *pBuf; + uint8_t *pEvtBuf; + + if ((pEvtBuf = lhciAllocCmdCmplEvt(paramLen, pCmdHdr->opCode)) == NULL) + { + return; + } + pBuf = pEvtBuf; + + switch (pCmdHdr->opCode) + { + /* --- command completion with status only parameter --- */ + + case HCI_OPCODE_LE_SET_CIG_PARAMS: + case HCI_OPCODE_LE_SET_CIG_PARAMS_TEST: + { + lhciPackSetCigParamsEvt(pBuf, status, numCis, cisHandles); + break; + } + case HCI_OPCODE_LE_REMOVE_CIG: + { + lhciPackRemoveCigEvt(pBuf, status); + break; + } + /* --- default --- */ + + default: + break; + } + + lhciSendCmdCmplEvt(pEvtBuf); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciMstCisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + const uint8_t MAX_CIS_COUNT = 16; + + switch (pHdr->opCode) + { + case HCI_OPCODE_LE_SET_CIG_PARAMS: + { + uint8_t cigId; + uint32_t sduIntervalMToS = 0; + uint32_t sduIntervalSToM = 0; + uint8_t sca; + uint8_t packing; + uint8_t framing; + uint16_t transLatMToS; + uint16_t transLatSToM; + + BSTREAM_TO_UINT8(cigId, pBuf); + BSTREAM_TO_UINT24(sduIntervalMToS, pBuf); + BSTREAM_TO_UINT24(sduIntervalSToM, pBuf); + BSTREAM_TO_UINT8(sca, pBuf); + BSTREAM_TO_UINT8(packing, pBuf); + BSTREAM_TO_UINT8(framing, pBuf); + BSTREAM_TO_UINT16(transLatMToS, pBuf); + BSTREAM_TO_UINT16(transLatSToM, pBuf); + BSTREAM_TO_UINT8(numCis, pBuf); + + LlCisCigParams_t cigParam; + + LlCisCisParams_t cisParam[MAX_CIS_COUNT]; + + for (unsigned int i = 0; i < WSF_MIN(numCis, MAX_CIS_COUNT); i++) + { + BSTREAM_TO_UINT8(cisParam[i].cisId, pBuf); + BSTREAM_TO_UINT16(cisParam[i].sduSizeMToS, pBuf); + BSTREAM_TO_UINT16(cisParam[i].sduSizeSToM, pBuf); + BSTREAM_TO_UINT8(cisParam[i].phyMToS, pBuf); + BSTREAM_TO_UINT8(cisParam[i].phySToM, pBuf); + BSTREAM_TO_UINT8(cisParam[i].rteMToS, pBuf); + BSTREAM_TO_UINT8(cisParam[i].rteSToM, pBuf); + } + + cigParam.cigId = cigId; + cigParam.sduIntervalMToS = sduIntervalMToS; + cigParam.sduIntervalSToM = sduIntervalSToM; + cigParam.sca = sca; + cigParam.packing = packing; + cigParam.framing = framing; + cigParam.transLatMToS = transLatMToS; + cigParam.transLatSToM = transLatSToM; + cigParam.numCis = numCis; + cigParam.pCisParam = &cisParam[0]; + + status = LlSetCigParams(&cigParam, cisHandles); + paramLen = 3 + numCis * 2; + break; + } + case HCI_OPCODE_LE_SET_CIG_PARAMS_TEST: + { + uint8_t cigId; + uint32_t sduIntervalMToS = 0; + uint32_t sduIntervalSToM = 0; + uint8_t ftMToS; + uint8_t ftSToM; + uint16_t isoInterval; + uint8_t sca; + uint8_t packing; + uint8_t framing; + + BSTREAM_TO_UINT8(cigId, pBuf); + BSTREAM_TO_UINT24(sduIntervalMToS, pBuf); + BSTREAM_TO_UINT24(sduIntervalSToM, pBuf); + BSTREAM_TO_UINT8(ftMToS, pBuf); + BSTREAM_TO_UINT8(ftSToM, pBuf); + BSTREAM_TO_UINT16(isoInterval, pBuf); + BSTREAM_TO_UINT8(sca, pBuf); + BSTREAM_TO_UINT8(packing, pBuf); + BSTREAM_TO_UINT8(framing, pBuf); + BSTREAM_TO_UINT8(numCis, pBuf); + + LlCisCigParamsTest_t cigParam; + + LlCisCigCisParamsTest_t cisParam[LL_MAX_CIS]; + + for (unsigned int i = 0; i < WSF_MIN(numCis, LL_MAX_CIS); i++) + { + BSTREAM_TO_UINT8(cisParam[i].cisId, pBuf); + BSTREAM_TO_UINT8(cisParam[i].nse, pBuf); + BSTREAM_TO_UINT16(cisParam[i].sduSizeMToS, pBuf); + BSTREAM_TO_UINT16(cisParam[i].sduSizeSToM, pBuf); + BSTREAM_TO_UINT16(cisParam[i].pduSizeMToS, pBuf); + BSTREAM_TO_UINT16(cisParam[i].pduSizeSToM, pBuf); + BSTREAM_TO_UINT8(cisParam[i].phyMToS, pBuf); + BSTREAM_TO_UINT8(cisParam[i].phySToM, pBuf); + BSTREAM_TO_UINT8(cisParam[i].bnMToS, pBuf); + BSTREAM_TO_UINT8(cisParam[i].bnSToM, pBuf); + } + + cigParam.cigId = cigId; + cigParam.sduIntervalMToS = sduIntervalMToS; + cigParam.sduIntervalSToM = sduIntervalSToM; + cigParam.ftMToS = ftMToS; + cigParam.ftSToM = ftSToM; + cigParam.isoInterval = isoInterval; + cigParam.sca = sca; + cigParam.packing = packing; + cigParam.framing = framing; + cigParam.numCis = numCis; + cigParam.pCisParam = &cisParam[0]; + + status = LlSetCigParamsTest(&cigParam, cisHandles); + paramLen = 3 + numCis * 2; + break; + } + case HCI_OPCODE_LE_CREATE_CIS: + { + BSTREAM_TO_UINT8(numCis, pBuf); + LlCisCreateCisParams_t createCisParam; + uint16_t aclHandle[LL_MAX_CIS]; + uint16_t cisHandle[LL_MAX_CIS]; + + for (unsigned int i = 0; i < WSF_MIN(numCis, LL_MAX_CIS); i++) + { + BSTREAM_TO_UINT16 (cisHandle[i], pBuf); + BSTREAM_TO_UINT16 (aclHandle[i], pBuf); + } + createCisParam.pCisHandle = &cisHandle[0]; + createCisParam.pAclHandle = &aclHandle[0]; + status = LlCreateCis(numCis, &createCisParam); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + case HCI_OPCODE_LE_REMOVE_CIG: + { + uint8_t cigId; + + BSTREAM_TO_UINT8(cigId, pBuf); + status = LlRemoveCig(cigId); + + paramLen = LHCI_LEN_LE_REMOVE_CIG; + + break; + } + + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen == LHCI_LEN_CMD_STATUS_EVT) + { + lhciSendCmdStatusEvt(pHdr, status); + } + else if (paramLen > 0) + { + lhciCisMstSendCmdCmplEvt(pHdr, status, paramLen); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_slave.c new file mode 100644 index 00000000000..86ae7329343 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_cis_slave.c @@ -0,0 +1,138 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "ll_defs.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Build and send a command complete event packet. + * + * \param pCmdHdr Command HCI header. + * \param status Status value. + * \param paramLen Parameter length of the command status event. + * \param handle Handle. + */ +/*************************************************************************************************/ +static void lhciCisSlvSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *pEvtBuf; + + if ((pEvtBuf = lhciAllocCmdCmplEvt(paramLen, pCmdHdr->opCode)) == NULL) + { + return; + } + pBuf = pEvtBuf; + + switch (pCmdHdr->opCode) + { + /* --- command completion with status only parameter --- */ + case HCI_OPCODE_LE_ACCEPT_CIS_REQ: + { + break; + } + case HCI_OPCODE_LE_REJECT_CIS_REQ: + { + lhciPackCmdCompleteEvtStatus(pBuf, status); + break; + } + /* --- default --- */ + + default: + break; + } + + lhciSendCmdCmplEvt(pEvtBuf); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciSlvCisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + uint16_t handle = 0; + + switch (pHdr->opCode) + { + case HCI_OPCODE_LE_ACCEPT_CIS_REQ: + { + uint16_t cisHandle; + + BSTREAM_TO_UINT16(cisHandle, pBuf); + status = LlAcceptCisReq(cisHandle); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + + case HCI_OPCODE_LE_REJECT_CIS_REQ: + { + uint16_t cisHandle; + uint8_t reason; + + BSTREAM_TO_UINT16(cisHandle, pBuf); + BSTREAM_TO_UINT8(reason, pBuf); + status = LlRejectCisReq(cisHandle, reason); + paramLen = LHCI_LEN_LE_REJECT_CIS_REQ; + break; + } + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen == LHCI_LEN_CMD_STATUS_EVT) + { + lhciSendCmdStatusEvt(pHdr, status); + } + else if (paramLen > 0) + { + lhciCisSlvSendCmdCmplEvt(pHdr, status, paramLen, handle); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn.c index 21334737fd2..b2ad1ac383e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -68,7 +69,7 @@ uint8_t lhciUnpackConnSpec(LlConnSpec_t *pConnSpec, const uint8_t *pBuf) /*************************************************************************************************/ static uint8_t lhciPackReadPwrLevel(uint8_t *pBuf, uint8_t status, uint16_t handle, int8_t level) { - const uint8_t len = LHCI_LEN_READ_LOCAL_VER_EVT; + const uint8_t len = LHCI_LEN_READ_PWR_LVL_EVT; UINT8_TO_BSTREAM (pBuf, status); UINT16_TO_BSTREAM(pBuf, handle); @@ -86,8 +87,6 @@ static uint8_t lhciPackReadPwrLevel(uint8_t *pBuf, uint8_t status, uint16_t hand * \param paramLen Parameter length of the command status event. * \param pParam Parameter buffer. * \param handle Connection handle. - * - * \return None. */ /*************************************************************************************************/ void lhciConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam, uint16_t handle) @@ -107,7 +106,6 @@ void lhciConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN: case HCI_OPCODE_LE_SET_PER_ADV_RCV_ENABLE: - case HCI_OPCODE_LE_SET_PAST_PARAM: case HCI_OPCODE_LE_SET_DEFAULT_PAST_PARAM: lhciPackCmdCompleteEvtStatus(pBuf, status); break; @@ -119,6 +117,7 @@ void lhciConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen case HCI_OPCODE_LE_SET_DATA_LEN: case HCI_OPCODE_LE_PER_ADV_SYNC_TRANSFER: case HCI_OPCODE_LE_PER_ADV_SET_INFO_TRANSFER: + case HCI_OPCODE_LE_SET_PAST_PARAM: pBuf += lhciPackCmdCompleteEvtStatus(pBuf, status); UINT16_TO_BSTREAM(pBuf, handle); break; @@ -162,6 +161,7 @@ void lhciConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen lhciPackReadPwrLevel(pBuf, status, handle, level); break; } + case HCI_OPCODE_READ_RSSI: { int8_t rssi; @@ -355,8 +355,6 @@ bool_t lhciConnDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) * \param handle Connection handle. * \param pktLen Packet length. * \param numPkts Number of packets. - * - * \return None. */ /*************************************************************************************************/ void lhciGenerateAcl(uint16_t handle, uint16_t pktLen, uint8_t numPkts) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master.c index 8073b4b5182..adeb5a08367 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,8 +38,6 @@ * \param pCmdHdr Command HCI header. * \param status Status value. * \param paramLen Parameter length of the command status event. - * - * \return None. */ /*************************************************************************************************/ static void lhciMstConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master_ae.c index 76fd5ea96ba..0da42e76d94 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -41,7 +42,7 @@ * \param connSpec Unpacked connection specification table indexed by PHY. * \param pBuf Packed packet buffer. * - * \return None. + * \return Bytes unpacked. */ /*************************************************************************************************/ static uint8_t lhciUnpackExtInitParam(LlExtInitParam_t *pInitParam, LlExtInitScanParam_t initScanParam[], LlConnSpec_t connSpec[], const uint8_t *pBuf) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_priv.c index 45484d76e27..f391b2bd1b1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_conn_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -58,8 +59,6 @@ static uint8_t lhciPackReadResAddrEvt(uint8_t *pBuf, uint8_t status, const uint8 * \param status Status value. * \param paramLen Parameter length of the command status event. * \param pParam Pointer to parameters. - * - * \return None. */ /*************************************************************************************************/ static void lhciPrivConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_master.c index 40974ae4762..df01189e213 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_slave.c index 6f2a1722cb6..78772050db9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -103,8 +104,6 @@ static uint8_t lhciPackReadAuthPayloadTimeoutEvt(uint8_t *pBuf, uint8_t status, * \param paramLen Parameter length of the command status event. * \param pParam Parameter buffer. * \param handle Connection handle. - * - * \return None. */ /*************************************************************************************************/ static void lhciSlvEncSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam, uint16_t handle) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_iso.c new file mode 100644 index 00000000000..0073a37187b --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_iso.c @@ -0,0 +1,587 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "ll_defs.h" +#include "pal_codec.h" +#include "wsf_msg.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +#define LHCI_MAX_CODEC 5 /*!< Maximum number of codecs to read from audio subsystem. */ + +/************************************************************************************************** + Type Definitions +**************************************************************************************************/ + +/*! \brief ISO return parameters. */ +typedef union +{ + struct + { + uint32_t minDly; /*!< Minimum controller delay. */ + uint32_t maxDly; /*!< Maximum controller delay. */ + } ctrDly; /*!< Read local supported controller delay return parameters. */ +} lhciIsoReturnParam_t; + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a read ISO buffer size event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param aclPktLen ACL data packet length. + * \param aclNumPkts Number of controller ACL data packet buffers. + * \param isoBufSize ISO data packet length. + * \param numIsoPkts Number of controller ISO data packet buffers. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackReadBufSizeV2Evt(uint8_t *pBuf, uint8_t status, uint16_t aclPktLen, uint8_t aclNumPkts, + uint16_t isoBufSize, uint8_t numIsoPkts) +{ + const uint8_t len = LHCI_LEN_LE_READ_BUF_SIZE_V2; + + UINT8_TO_BSTREAM (pBuf, status); + UINT16_TO_BSTREAM(pBuf, aclPktLen); + UINT8_TO_BSTREAM (pBuf, aclNumPkts); + UINT16_TO_BSTREAM(pBuf, isoBufSize); + UINT8_TO_BSTREAM (pBuf, numIsoPkts); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a read ISO buffer size event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * \param pktSn Packet sequence number. + * \param ts Timestamp. + * \param timeOffs Time offset. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackReadIsoTxSyncEvt(uint8_t *pBuf, uint8_t status, uint16_t handle, uint16_t pktSn, + uint32_t ts, uint32_t timeOffs) +{ + const uint8_t len = LHCI_LEN_LE_READ_TX_SYNC; + + UINT8_TO_BSTREAM (pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + UINT16_TO_BSTREAM(pBuf, pktSn); + UINT32_TO_BSTREAM(pBuf, ts); + UINT24_TO_BSTREAM(pBuf, timeOffs); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a read ISO test counter command complete event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * \param pCtr ISO test counters. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackIsoReadTestCounters(uint8_t *pBuf, uint8_t status, uint16_t handle, LlIsoTestCtrs_t *pCtr) +{ + const uint8_t len = LHCI_LEN_LE_ISO_READ_TEST_COUNTER; + + UINT8_TO_BSTREAM (pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + UINT32_TO_BSTREAM(pBuf, pCtr->numSuccess); + UINT32_TO_BSTREAM(pBuf, pCtr->numMissed); + UINT32_TO_BSTREAM(pBuf, pCtr->numFailed); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack a read ISO link quality command complete event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * \param LinkQualStats Link quality stats. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackReadIsoLinkQuality(uint8_t *pBuf, uint8_t status, uint16_t handle, LlIsoLinkQual_t LinkQualStats) +{ + const uint8_t len = LHCI_LEN_LE_READ_ISO_LINK_QUAL; + + UINT8_TO_BSTREAM (pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.txUnAckPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.txFlushedPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.txLastSubEventPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.retransmitPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.crcErrPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.rxUnreceivedPkt); + UINT32_TO_BSTREAM(pBuf, LinkQualStats.duplicatePkt); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack setup data path event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackSetupDataPathEvt(uint8_t *pBuf, uint8_t status, uint16_t handle) +{ + const uint8_t len = LHCI_LEN_LE_SETUP_ISO_DATA_PATH; + + UINT8_TO_BSTREAM(pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack remove data path event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackRemoveDataPathEvt(uint8_t *pBuf, uint8_t status, uint16_t handle) +{ + const uint8_t len = LHCI_LEN_LE_REMOVE_ISO_DATA_PATH; + + UINT8_TO_BSTREAM(pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Pack read local supported codecs event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param numStd Number of standard codecs. + * \param stdCodecs Table of standard codec info. + * \param numVs Number of vendor specific codecs. + * \param vsCodecs Table of vendor specific codec info. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackReadLocalSupportedCodecs(uint8_t *pBuf, uint8_t status, + uint8_t numStd, AudioStdCodecInfo_t stdCodecs[], + uint8_t numVs, AudioVsCodecInfo_t vsCodecs[]) +{ + uint8_t len = LHCI_LEN_READ_LOCAL_SUP_CODECS; + + UINT8_TO_BSTREAM(pBuf, status); + UINT8_TO_BSTREAM(pBuf, numStd); + + for (size_t i = 0; i < numStd; i++) + { + UINT8_TO_BSTREAM(pBuf, stdCodecs[i].codecId); + UINT8_TO_BSTREAM(pBuf, LL_CODEC_TRANS_CIS_BIT | LL_CODEC_TRANS_BIS_BIT); + len += sizeof(uint8_t) + sizeof(uint8_t); + } + + UINT8_TO_BSTREAM(pBuf, numVs); + + for (size_t i = 0; i < numVs; i++) + { + UINT16_TO_BSTREAM(pBuf, vsCodecs[i].compId); + UINT16_TO_BSTREAM(pBuf, vsCodecs[i].codecId); + UINT8_TO_BSTREAM(pBuf, LL_CODEC_TRANS_CIS_BIT | LL_CODEC_TRANS_BIS_BIT); + len += sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t); + } + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Build and send a command complete event packet. + * + * \param pCmdHdr Command HCI header. + * \param status Status value. + * \param paramLen Parameter length of the command status event. + * \param handle Connection handle. + * \param pRet Return parameters. + */ +/*************************************************************************************************/ +static void lhciIsoSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint16_t handle, const lhciIsoReturnParam_t *pRet) +{ + uint8_t *pBuf; + uint8_t *pEvtBuf; + + if ((pEvtBuf = lhciAllocCmdCmplEvt(paramLen, pCmdHdr->opCode)) == NULL) + { + return; + } + pBuf = pEvtBuf; + + switch (pCmdHdr->opCode) + { + case HCI_OPCODE_LE_READ_BUF_SIZE_V2: + { + lhciPackReadBufSizeV2Evt(pBuf, status, LlGetAclMaxSize(), LlGetAclTxBufs(), + LlGetIsoMaxBufSize(), LlGetIsoTxBufs()); + break; + } + case HCI_OPCODE_LE_READ_ISO_TX_SYNC: + { + uint16_t pktSn; + uint32_t ts; + uint32_t timeOffs; + + status = LlReadIsoTxSync(handle, &pktSn, &ts, &timeOffs); + lhciPackReadIsoTxSyncEvt(pBuf, status, handle, pktSn, ts, timeOffs); + break; + } + case HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH: + { + lhciPackRemoveDataPathEvt(pBuf, status, handle); + break; + } + case HCI_OPCODE_LE_SETUP_ISO_DATA_PATH: + { + lhciPackSetupDataPathEvt(pBuf, status, handle); + break; + } + case HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS: + { + LlIsoTestCtrs_t ctr; + + status = LlIsoReadTestCounter(handle, &ctr); + + lhciPackIsoReadTestCounters(pBuf, status, handle, &ctr); + break; + } + case HCI_OPCODE_LE_ISO_TEST_END: + { + LlIsoTestCtrs_t ctr; + status = LlIsoTestEnd(handle, &ctr); + + if (status == LL_SUCCESS) + { + lhciIsoCb.isoRxTest = FALSE; + } + + /* ISO Test End command complete event is identical to ISO Read Test Counters. */ + lhciPackIsoReadTestCounters(pBuf, status, handle, &ctr); + break; + } + case HCI_OPCODE_LE_READ_ISO_LINK_QUAL: + { + LlIsoLinkQual_t qualStats; + status = LlReadIsoLinkQual(handle, &qualStats); + lhciPackReadIsoLinkQuality(pBuf, status, handle, qualStats); + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CODECS: + { + uint8_t numStdCodecs = LHCI_MAX_CODEC; + AudioStdCodecInfo_t stdCodecs[LHCI_MAX_CODEC]; + uint8_t numVsCodecs = LHCI_MAX_CODEC; + AudioVsCodecInfo_t vsCodecs[LHCI_MAX_CODEC]; + + PalCodecReadLocalSupportedCodecs(&numStdCodecs, stdCodecs, + &numVsCodecs, vsCodecs); + + paramLen = lhciPackReadLocalSupportedCodecs(pBuf, status, + numStdCodecs, stdCodecs, + numVsCodecs, vsCodecs); + + /* Re-pack the event header now that the actual length is known. */ + lhciPackEvtHdr(pEvtBuf - (HCI_EVT_HDR_LEN + HCI_LEN_CMD_CMPL), HCI_CMD_CMPL_EVT, HCI_LEN_CMD_CMPL + paramLen); + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP: + { + UINT8_TO_BSTREAM(pBuf, status); + UINT8_TO_BSTREAM(pBuf, 0); /* Num_Codec_Capabilities */ + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY: + { + UINT8_TO_BSTREAM (pBuf, status); + UINT24_TO_BSTREAM(pBuf, pRet->ctrDly.minDly); /* Min_Controller_Delay */ + UINT24_TO_BSTREAM(pBuf, pRet->ctrDly.maxDly); /* Max_Controller_Delay */ + break; + } + + /* --- command completion with status only parameter --- */ + + case HCI_OPCODE_LE_ISO_TX_TEST: + case HCI_OPCODE_LE_ISO_RX_TEST: + case HCI_OPCODE_CONFIG_DATA_PATH: + { + LhciPackCmdCompleteEvtStatus(pBuf, status); + break; + } + + /* --- default --- */ + + default: + break; + } + + lhciSendCmdCmplEvt(pEvtBuf); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciIsoDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ +#if LHCI_ENABLE_VS + if (lhciIsoVsStdDecodeCmdPkt(pHdr, pBuf)) + { + return TRUE; + } +#endif + + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + uint16_t handle = 0; + lhciIsoReturnParam_t ret; + + switch (pHdr->opCode) + { + case HCI_OPCODE_LE_READ_BUF_SIZE_V2: + { + paramLen = LHCI_LEN_LE_READ_BUF_SIZE_V2; + break; + } + case HCI_OPCODE_LE_READ_ISO_TX_SYNC: + { + BSTREAM_TO_UINT16(handle, pBuf); + + paramLen = LHCI_LEN_LE_READ_TX_SYNC; + break; + } + case HCI_OPCODE_LE_ISO_TX_TEST: + { + uint8_t pldType; + + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (pldType, pBuf); + + status = LlIsoTxTest(handle, pldType); + paramLen = LHCI_LEN_LE_ISO_TX_TEST; + break; + } + case HCI_OPCODE_LE_ISO_RX_TEST: + { + uint8_t pldType; + + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (pldType, pBuf); + + status = LlIsoRxTest(handle, pldType); + paramLen = LHCI_LEN_LE_ISO_RX_TEST; + + if (status == LL_SUCCESS) + { + lhciIsoCb.isoRxTest = TRUE; + } + break; + } + case HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS: + { + BSTREAM_TO_UINT16(handle, pBuf); + paramLen = LHCI_LEN_LE_ISO_READ_TEST_COUNTER; + break; + } + case HCI_OPCODE_LE_ISO_TEST_END: + { + BSTREAM_TO_UINT16(handle, pBuf); + paramLen = LHCI_LEN_LE_ISO_TEST_END; + break; + } + case HCI_OPCODE_LE_READ_ISO_LINK_QUAL: + { + BSTREAM_TO_UINT16(handle, pBuf); + paramLen = LHCI_LEN_LE_READ_ISO_LINK_QUAL; + break; + } + case HCI_OPCODE_LE_SETUP_ISO_DATA_PATH: + { + LlIsoSetupDataPath_t param; + + BSTREAM_TO_UINT16(param.handle, pBuf); + BSTREAM_TO_UINT8 (param.dpDir, pBuf); + BSTREAM_TO_UINT8 (param.dpId, pBuf); + BSTREAM_TO_UINT8 (param.codecFormat, pBuf); + BSTREAM_TO_UINT16(param.codecCompId, pBuf); + BSTREAM_TO_UINT16(param.codecId, pBuf); + BSTREAM_TO_UINT24(param.ctrDly, pBuf); + BSTREAM_TO_UINT8 (param.codecConfigLen, pBuf); + param.pCodecConfig = pBuf; + status = LlSetupIsoDataPath(¶m); + handle = param.handle; + paramLen = LHCI_LEN_LE_SETUP_ISO_DATA_PATH; + break; + } + case HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH: + { + uint8_t dpDir; + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (dpDir, pBuf); + status = LlRemoveIsoDataPath(handle, dpDir); + paramLen = LHCI_LEN_LE_REMOVE_ISO_DATA_PATH; + break; + } + case HCI_OPCODE_CONFIG_DATA_PATH: + { + uint8_t dir; + uint8_t dataPathId; + BSTREAM_TO_UINT8 (dir, pBuf); + BSTREAM_TO_UINT8 (dataPathId, pBuf); + if (!PalCodecConfigureDataPath(dir, dataPathId)) + { + status = HCI_ERR_INVALID_PARAM; + } + paramLen = LHCI_LEN_CONFIG_DATA_PATH; + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CODECS: + { + /* Reserve maximum buffer size, re-pack length once size is known. */ + paramLen = LHCI_LEN_READ_LOCAL_SUP_CODECS + + (LHCI_MAX_CODEC * 2) + /* Max standard codecs */ + (LHCI_MAX_CODEC * 5); /* Max VS codecs */ + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP: + { + uint8_t codingFmt; + uint16_t compId; + uint16_t vsCodecId; + uint8_t transType; + uint8_t dir; + BSTREAM_TO_UINT8 (codingFmt, pBuf); + BSTREAM_TO_UINT16(compId, pBuf); + BSTREAM_TO_UINT16(vsCodecId, pBuf); + BSTREAM_TO_UINT8 (transType, pBuf); + BSTREAM_TO_UINT8 (dir, pBuf); + + if (PalCodecReadLocalSupportedCodecCapabilities(codingFmt, compId, vsCodecId, dir)) + { + if ((transType & (LL_CODEC_TRANS_CIS_BIT | LL_CODEC_TRANS_BIS_BIT)) == 0) + { + status = HCI_ERR_INVALID_PARAM; + } + } + else + { + status = HCI_ERR_INVALID_PARAM; + } + + paramLen = LHCI_LEN_READ_LOCAL_SUP_CODEC_CAP; + break; + } + case HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY: + { + uint8_t codingFmt; + uint16_t compId; + uint16_t vsCodecId; + uint8_t transType; + uint8_t dir; + BSTREAM_TO_UINT8 (codingFmt, pBuf); + BSTREAM_TO_UINT16(compId, pBuf); + BSTREAM_TO_UINT16(vsCodecId, pBuf); + BSTREAM_TO_UINT8 (transType, pBuf); + BSTREAM_TO_UINT8 (dir, pBuf); + ret.ctrDly.minDly = ret.ctrDly.maxDly = 0; + if (PalCodecReadLocalSupportedControllerDelay(codingFmt, compId, vsCodecId, dir, + &ret.ctrDly.minDly, &ret.ctrDly.maxDly)) + { + if ((transType & (LL_CODEC_TRANS_CIS_BIT | LL_CODEC_TRANS_BIS_BIT)) == 0) + { + status = HCI_ERR_INVALID_PARAM; + } + } + else + { + status = HCI_ERR_INVALID_PARAM; + } + paramLen = LHCI_LEN_READ_LOCAL_SUP_CONTROLLER_DLY; + break; + } + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen > 0) + { + lhciIsoSendCmdCmplEvt(pHdr, status, paramLen, handle, &ret); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_past.c index 853533ff425..6523399001d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_pc.c new file mode 100644 index 00000000000..e557b2930a6 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_pc.c @@ -0,0 +1,215 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief HCI command module implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "ll_defs.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Pack a read enhanced Tx power level or RSSI event packet. + * + * \param pBuf Packed packet buffer. + * \param status Completion status. + * \param handle Connection handle. + * \param curPwr Current Tx power level. + * \param maxPwr Maximum Tx power level. + * \param phy PHY read. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackEnhancedReadPwrLevel(uint8_t *pBuf, uint8_t status, uint16_t handle, int8_t curPwr, int8_t maxPwr, uint8_t phy) +{ + const uint8_t len = LHCI_LEN_LE_READ_ENH_TX_POWER_EVT; + + UINT8_TO_BSTREAM (pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + UINT8_TO_BSTREAM (pBuf, phy); + UINT8_TO_BSTREAM (pBuf, curPwr); + UINT8_TO_BSTREAM (pBuf, maxPwr); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Build and send a command complete event packet. + * + * \param pCmdHdr Command HCI header. + * \param status Status value. + * \param paramLen Parameter length of the command status event. + * \param pParam Parameter buffer. + * \param handle Connection handle. + */ +/*************************************************************************************************/ +void lhciPclSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam, uint16_t handle) +{ + uint8_t *pBuf; + uint8_t *pEvtBuf; + + if ((pEvtBuf = lhciAllocCmdCmplEvt(paramLen, pCmdHdr->opCode)) == NULL) + { + return; + } + pBuf = pEvtBuf; + + switch (pCmdHdr->opCode) + { + /* --- command completion with status and connHandle parameters --- */ + + case HCI_OPCODE_LE_SET_TX_POWER_REPORT_ENABLE: + case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_PARAMS: + case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_ENABLE: + pBuf += lhciPackCmdCompleteEvtStatus(pBuf, status); + UINT16_TO_BSTREAM(pBuf, handle); + break; + + /* --- status --- */ + case HCI_OPCODE_LE_READ_ENHANCED_TX_POWER: + { + int8_t curPwr = 0; + int8_t maxPwr = 0; + uint8_t phy; + BSTREAM_TO_UINT8(phy, pParam); + status = LlGetEnhTxPowerLevel(handle, phy, &curPwr, &maxPwr); + lhciPackEnhancedReadPwrLevel(pBuf, status, handle, curPwr, maxPwr, phy); + break; + } + + /* --- default --- */ + + default: + break; + } + + lhciSendCmdCmplEvt(pEvtBuf); +} + +/*************************************************************************************************/ +/*! + * \brief Decode an HCI command packet. + * + * \param pHdr Decoded packet header. + * \param pBuf Packed HCI packet buffer. + * + * Command processing is organized by urgency then by frequency of command calls during normal + * operation. The following grouping is used: + * - connection control + * - connection status + * - local device management + * - remote device management + * - default + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciPclDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t paramLen = 0; + uint8_t *pParam = NULL; + uint16_t handle = 0; + + switch (pHdr->opCode) + { + /* --- connection status --- */ + + case HCI_OPCODE_LE_READ_ENHANCED_TX_POWER: + BSTREAM_TO_UINT16(handle, pBuf); + paramLen = LHCI_LEN_LE_READ_ENH_TX_POWER_EVT; + pParam = pBuf; + break; + + + /* --- remote device management --- */ + case HCI_OPCODE_LE_READ_REMOTE_TX_POWER: + { + uint8_t phy; + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (phy, pBuf); + status = LlPowerCtrlReq(handle, 0, phy); + paramLen = LHCI_LEN_CMD_STATUS_EVT; + break; + } + case HCI_OPCODE_LE_SET_TX_POWER_REPORT_ENABLE: + { + uint8_t enableLocal; + uint8_t enableRemote; + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (enableLocal, pBuf); + BSTREAM_TO_UINT8 (enableRemote, pBuf); + status = LlSetTxPowerReporting(handle, enableLocal, enableRemote); + paramLen = LHCI_LEN_LE_SET_TX_POWER_REPORT_EVT; + break; + } + case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_PARAMS: + { + int8_t highThreshold; + int8_t highHysteresis; + int8_t lowThreshold; + int8_t lowHysteresis; + uint16_t minTimeSpent; + + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_INT8 (highThreshold, pBuf); + BSTREAM_TO_INT8 (highHysteresis, pBuf); + BSTREAM_TO_INT8 (lowThreshold, pBuf); + BSTREAM_TO_INT8 (lowHysteresis, pBuf); + BSTREAM_TO_UINT16(minTimeSpent, pBuf); + status = LlSetPathLossReportingParams(handle, highThreshold, highHysteresis, lowThreshold, lowHysteresis, minTimeSpent); + paramLen = LHCI_LEN_LE_SET_PATH_LOSS_REPORTING_PARAMS; + break; + } + case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_ENABLE: + { + uint8_t enable; + + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_INT8 (enable, pBuf); + status = LlSetPathLossReportingEnable(handle, enable); + paramLen = LHCI_LEN_LE_SET_PATH_LOSS_REPORTING_ENABLE; + break; + } + + /* --- default --- */ + + default: + return FALSE; /* exit dispatcher routine */ + } + + if (paramLen == LHCI_LEN_CMD_STATUS_EVT) + { + lhciSendCmdStatusEvt(pHdr, status); + } + else + { + lhciPclSendCmdCmplEvt(pHdr, status, paramLen, pParam, handle); + } + + return TRUE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_phy.c index 50715e72206..ddaed05ad9e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -63,8 +64,6 @@ static uint8_t lhciPackReadPhyEvt(uint8_t *pBuf, uint8_t status, uint16_t handle * \param status Status value. * \param paramLen Parameter length of the command status event. * \param handle Connection handle. - * - * \return None. */ /*************************************************************************************************/ static void lhciPhySendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint16_t handle) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_sc.c index 449176283a9..b20620129fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs.c index afe91ec9fee..b63fc099614 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,6 +28,7 @@ #include "ll_api.h" #include "pal_sys.h" #include "sch_api.h" +#include "bb_ble_sniffer_api.h" #include "wsf_assert.h" #include "wsf_buf.h" #include "wsf_cs.h" @@ -49,12 +51,12 @@ /*! \brief Get System Statistics command complete event length. */ /* stackWatermark(uint16_t) + palSysAssertCount(uint16_t) + - * freeMem (uint32_t) + usedMem(uint32_t) + - * connMax(uint16_t) + connCtxSize(uint16_t) + csWatermarkUsec(uint16_t) + llHandlerWatermarkUsec(uint16_t) + schHandlerWatermarkUsec(uint16_t) + lhciHandlerWatermarkUsec(uint16_t) + + * freeMem (uint32_t) + usedMem(uint32_t) + schDelayLoadTotalCount(uint32_t) + + * connMax(uint16_t) + connCtxSize(uint16_t) + csWatermarkUsec(uint16_t) + llHandlerWatermarkUsec(uint16_t) + schHandlerWatermarkUsec(uint16_t) + lhciHandlerWatermarkUsec(uint16_t) + schDelayLoadWatermarkCount(uint16_t) + * advSetMax(uint16_t) + advSetCtxSize(uint16_t) + * extScanMax(uint16_t) + extScanCtxSize(uint16_t) + extInitMax(uint16_t) + extInitCtxSize(uint16_t) + perScanMax(uint16_t) + perScanCtxSize(uint16_t) + cigMax(uint16_t) + cigCtxSize(uint16_t) + cisMax(uint16_t) + cisCtxSize(uint16_t) */ -#define LHCI_LEN_GET_SYS_STATS_EVT (2 * sizeof(uint16_t) + 2 * sizeof(uint32_t) + 6 * sizeof(uint16_t) + 2 * sizeof(uint16_t) + 10 * sizeof(uint16_t)) +#define LHCI_LEN_GET_SYS_STATS_EVT (2 * sizeof(uint16_t) + 3 * sizeof(uint32_t) + 7 * sizeof(uint16_t) + 2 * sizeof(uint16_t) + 10 * sizeof(uint16_t)) /************************************************************************************************** Functions @@ -62,7 +64,7 @@ /*************************************************************************************************/ /*! - * \brief Decode Cordio common vendor specific HCI command packet. + * \brief Decode Packetcraft common vendor specific HCI command packet. * * \param pHdr Unpacked command header. * \param pBuf Packed HCI packet buffer. @@ -97,12 +99,26 @@ bool_t lhciCommonVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) bool_t enable; uint64_t mask; BSTREAM_TO_UINT64(mask, pBuf); + BSTREAM_TO_UINT8 (enable, pBuf); + + if (mask & ((uint64_t)LHCI_VS_EVT_MASK_SCAN_REPORT_EVT) << LHCI_BYTE_TO_BITS(0)) + { + LlScanReportEnable(enable); + } + + if (mask & ((uint64_t)LHCI_VS_EVT_MASK_DIAG_TRACE_EVT) << LHCI_BYTE_TO_BITS(0)) + { + LL_TRACE_ENABLE(enable); + } - enable = !!(mask & ((uint64_t)LHCI_VS_EVT_MASK_SCAN_REPORT_EVT) << LHCI_BYTE_TO_BITS(0)); - LlScanReportEnable(enable); +#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) + /* TODO: Use function pointer to allow run time configuration of supported versions. */ + if (mask & ((uint64_t)LHCI_VS_EVT_MASK_ISO_EVENT_CMPL_EVT) << LHCI_BYTE_TO_BITS(0)) + { + LlIsoEventCompleteEnable(enable); + } +#endif - enable = !!(mask & ((uint64_t)LHCI_VS_EVT_MASK_DIAG_TRACE_EVT) << LHCI_BYTE_TO_BITS(0)); - LL_TRACE_ENABLE(enable); break; } case LHCI_OPCODE_VS_SET_TX_TEST_ERR_PATT: @@ -113,16 +129,13 @@ bool_t lhciCommonVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) status = LlSetTxTestErrorPattern(pattern); break; } - case LHCI_OPCODE_VS_SET_HCI_SUP_CMD: - { - uint8_t byte, bit; - bool_t enable; - BSTREAM_TO_UINT8(byte, pBuf); - BSTREAM_TO_UINT8(bit, pBuf); - BSTREAM_TO_UINT8(enable, pBuf); - status = LlSetHciSupCmd(byte, bit, enable); - break; - } + case LHCI_OPCODE_VS_SET_SNIFFER_ENABLE: +#if (BB_SNIFFER_ENABLED == TRUE) + status = BbBleInitSniffer(pBuf[0], pBuf[1]); +#else + status = HCI_ERR_UNKNOWN_CMD; +#endif + break; case LHCI_OPCODE_VS_SET_BD_ADDR: LlSetBdAddr(pBuf); @@ -176,7 +189,7 @@ bool_t lhciCommonVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) case LHCI_OPCODE_VS_SET_BD_ADDR: case LHCI_OPCODE_VS_GET_RAND_ADDR: case LHCI_OPCODE_VS_SET_TX_TEST_ERR_PATT: - case LHCI_OPCODE_VS_SET_HCI_SUP_CMD: + case LHCI_OPCODE_VS_SET_SNIFFER_ENABLE: /* no action */ break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master.c index 68e4b760ad4..52bb2940e32 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master_ae.c index 7dfb006c2fc..fd35ccaa41d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave.c index eb351265982..6532955b22e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave_ae.c index ee08da829d2..66cf6cfdb17 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn.c index 598c87396ac..e362abb5c17 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -87,13 +88,26 @@ bool_t lhciConnVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) status = LlSetConnOpFlags(handle, flags, enable); break; } + case LHCI_OPCODE_VS_SET_CONN_TX_PWR: { uint16_t handle; int8_t level; BSTREAM_TO_UINT16(handle, pBuf); BSTREAM_TO_UINT8 (level, pBuf); - status = LlSetTxPowerLevel(handle, level); + status = LlSetAllPhyTxPowerLevel(handle, level); + break; + } + + case LHCI_OPCODE_VS_SET_CONN_PHY_TX_PWR: + { + uint16_t handle; + int8_t level; + uint8_t phy; + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT8 (level, pBuf); + BSTREAM_TO_UINT8 (phy, pBuf); + status = LlSetPhyTxPowerLevel(handle, level, phy); break; } @@ -155,6 +169,7 @@ bool_t lhciConnVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) break; case LHCI_OPCODE_VS_SET_CONN_TX_PWR: + case LHCI_OPCODE_VS_SET_CONN_PHY_TX_PWR: /* no action */ break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn_master.c index c3dc8085619..3cd8929f5bc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_enc_slave.c index 9c53df29161..e22e5697c04 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_ext.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_ext.c deleted file mode 100644 index c9ced2ed7aa..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_ext.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Extended vendor specific HCI command module implementation file. - */ -/*************************************************************************************************/ - -#include "lhci_api.h" - -/*************************************************************************************************/ -/*! - * \brief Decode extended vendor specific HCI command packet. - * - * \param pHdr Unpacked command header. - * \param pBuf Packed HCI packet buffer. - * - * Command processing for vendor specific commands. - * - * \return TRUE if opcode handled, FALSE otherwise. - */ -/*************************************************************************************************/ -bool_t lhciVsExtDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) -{ - return FALSE; -} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_iso.c new file mode 100644 index 00000000000..90731fb38cb --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_iso.c @@ -0,0 +1,164 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Arm Ltd. vendor specific HCI command module implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "hci_defs.h" +#include "bb_ble_api.h" +#include "ll_api.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/*! \brief Control block for ISO generation. */ +lhciIsoCb_t lhciIsoCb; + +/*************************************************************************************************/ +/*! + * \brief Decode Arm Ltd. connection vendor specific HCI command packet. + * + * \param pHdr Unpacked command header. + * \param pBuf Packed HCI packet buffer. + * + * Command processing for vendor specific commands. + * + * \return TRUE if opcode handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciIsoVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf) +{ + uint8_t status = HCI_SUCCESS; + uint8_t evtParamLen = 1; /* default is status field only */ + + /* Decode and consume command packet. */ + switch (pHdr->opCode) + { + /* --- ISO --- */ + + case LHCI_OPCODE_VS_GET_ISO_TEST_REPORT: + evtParamLen += sizeof(uint32_t) * 4; + break; + case LHCI_OPCODE_VS_ENA_ISO_SINK: + lhciIsoCb.recvIsoSink = pBuf[0]; + break; + case LHCI_OPCODE_VS_ENA_AUTO_GEN_ISO: + BSTREAM_TO_UINT16(lhciIsoCb.genPktLen, pBuf); + break; + case LHCI_OPCODE_VS_GENERATE_ISO: + { + uint16_t handle; + uint16_t pktLen; + uint8_t numPkts; + + BSTREAM_TO_UINT16(handle, pBuf); + BSTREAM_TO_UINT16(pktLen, pBuf); + numPkts = *pBuf++; + + lhciGenerateIso(handle, pktLen, numPkts); + break; + } + case LHCI_OPCODE_VS_GET_CIS_STATS: + evtParamLen += sizeof(BbBleDataPktStats_t); + break; + + /* --- default --- */ + + default: + return FALSE; /* exit dispatcher routine */ + } + + uint8_t *pEvtBuf; + + /* Encode and send command complete event packet. */ + if ((pEvtBuf = lhciAllocCmdCmplEvt(evtParamLen, pHdr->opCode)) != NULL) + { + pBuf = pEvtBuf; + pBuf += lhciPackCmdCompleteEvtStatus(pBuf, status); + + switch (pHdr->opCode) + { + case LHCI_OPCODE_VS_GET_ISO_TEST_REPORT: + UINT32_TO_BSTREAM(pBuf, lhciIsoCb.recvIsoPktCnt); + UINT32_TO_BSTREAM(pBuf, lhciIsoCb.recvIsoOctetCnt); + UINT32_TO_BSTREAM(pBuf, lhciIsoCb.genPktCnt); + UINT32_TO_BSTREAM(pBuf, lhciIsoCb.genOctetCnt); + break; + + case LHCI_OPCODE_VS_GET_CIS_STATS: + { + BbBleDataPktStats_t stats; + BbBleGetCisStats(&stats); + memcpy(pBuf, (uint8_t *)&stats, sizeof(stats)); + break; + } + + /* --- default --- */ + + default: + break; + } + + lhciSendCmdCmplEvt(pEvtBuf); + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Generate ISO packets. + * + * \param handle Connection handle. + * \param pktLen Packet length. + * \param numPkts Number of packets. + */ +/*************************************************************************************************/ +void lhciGenerateIso(uint16_t handle, uint16_t pktLen, uint8_t numPkts) +{ + if (lhciIsoCb.genEnaFlag) + { + /* Prevent re-entrance. */ + return; + } + + lhciIsoCb.genEnaFlag = TRUE; + + while (numPkts--) + { + uint8_t *pIsoBuf; + if ((pIsoBuf = (uint8_t*)WsfMsgAlloc(LL_ISO_PDU_MAX_LEN)) == NULL) + { + break; + } + + uint8_t *pBuf = pIsoBuf; + UINT16_TO_BSTREAM(pBuf, handle & 0xFFF); /* BTS=0 and BF=0 */ + UINT16_TO_BSTREAM(pBuf, pktLen); + memset(pBuf, lhciIsoCb.genPldCnt++, pktLen); + + LlSendIsoData(pIsoBuf); + } + + lhciIsoCb.genEnaFlag = FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_sc.c index 27f831592f9..9af929cf782 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_cmd_vs_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Arm Ltd. vendor specific HCI command module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Arm Ltd. vendor specific HCI command module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt.c index 41358ad291d..d613ba1f07a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -108,8 +109,6 @@ bool_t lhciLlEvtHandler(LlEvt_t *pEvt) WSF_ASSERT(lhciEvtTbl[LHCI_MSG_ADV]); /* proper init guarantees this handler exists. */ - LL_TRACE_INFO1("Encoding LL event=%u", pEvt->hdr.event); - /* Standard event handlers. */ do { @@ -165,8 +164,6 @@ bool_t lhciLlEvtHandler(LlEvt_t *pEvt) * \brief Send an HCI event and service the event queue. * * \param pBuf Buffer containing HCI event to send or NULL to service the queue. - * - * \return None. */ /*************************************************************************************************/ void LhciSendEvent(uint8_t *pBuf) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master.c index 1dcd4833023..a2d53fb0ca7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master_ae.c index e5304111ba5..66353613401 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -99,8 +100,6 @@ static uint8_t *lhciAllocPerAdvRptEvt(uint8_t evtCode, uint8_t paramLen) * \param pEvt Extended advertising report indication data. * \param pFragStart Start of fragmentation buffer. * \param fragLen Length of fragment. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackExtAdvRptEvt(uint8_t *pBuf, const LlExtAdvReportInd_t *pEvt, @@ -142,8 +141,6 @@ static void lhciPackExtAdvRptEvt(uint8_t *pBuf, const LlExtAdvReportInd_t *pEvt, * \param pEvt Periodic advertising report indication data. * \param pFragStart Start of fragmentation buffer. * \param fragLen Length of fragment. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackPerAdvRptEvt(uint8_t *pBuf, const LlPerAdvReportInd_t *pEvt, @@ -187,8 +184,6 @@ static void lhciPackPerAdvRptEvt(uint8_t *pBuf, const LlPerAdvReportInd_t *pEvt, * * \param pBuf Packed packet buffer. * \param pEvt Periodic advertising sync established event confirmation. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackPerAdvSyncEstdEvt(uint8_t *pBuf, const LlPerAdvSyncEstdCnf_t *pEvt) @@ -210,8 +205,6 @@ static void lhciPackPerAdvSyncEstdEvt(uint8_t *pBuf, const LlPerAdvSyncEstdCnf_t * * \param pBuf Packed packet buffer. * \param pEvt Periodic advertising sync lost event confirmation. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackPerAdvSyncLostEvt(uint8_t *pBuf, const LlPerAdvSyncLostInd_t *pEvt) @@ -226,8 +219,6 @@ static void lhciPackPerAdvSyncLostEvt(uint8_t *pBuf, const LlPerAdvSyncLostInd_t * * \param pBuf Packed packet buffer. * \param pEvt Periodic advertising sync transfer received event indication. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackPerSyncTrsfRcvdEvt(uint8_t *pBuf, const LlPerSyncTrsfRcvdInd_t *pEvt) @@ -272,7 +263,7 @@ bool_t lhciMstExtScanEncodeEvtPkt(LlEvt_t *pEvt) if ((lhciCb.numAdvReport + num_buffers) > pLctrRtCfg->maxAdvReports) { - LL_TRACE_WARN0("LL_EXT_ADV_REPORT_IND, discarded, not enough advRport buffers available."); + LL_TRACE_WARN0("LL_EXT_ADV_REPORT_IND, discarded, not enough advRport buffers available"); break; } @@ -293,7 +284,7 @@ bool_t lhciMstExtScanEncodeEvtPkt(LlEvt_t *pEvt) /* Drop remaining fragments. */ remDataLen = 0; - LL_TRACE_WARN0("LL_EXT_ADV_REPORT_IND, truncated, not enough advRport buffers."); + LL_TRACE_WARN0("LL_EXT_ADV_REPORT_IND, truncated, not enough advRport buffers"); } else { @@ -366,7 +357,7 @@ bool_t lhciMstExtScanEncodeEvtPkt(LlEvt_t *pEvt) if ((lhciCb.numAdvReport + num_buffers) > pLctrRtCfg->maxAdvReports) { - LL_TRACE_WARN0("LL_PER_ADV_REPORT_IND, discarded, not enough advRport buffers available."); + LL_TRACE_WARN0("LL_PER_ADV_REPORT_IND, discarded, not enough advRport buffers available"); break; } @@ -386,7 +377,7 @@ bool_t lhciMstExtScanEncodeEvtPkt(LlEvt_t *pEvt) /* Drop remaining fragments. */ remDataLen = 0; - LL_TRACE_WARN0("LL_PER_ADV_REPORT_IND, truncated, not enough advRport buffers."); + LL_TRACE_WARN0("LL_PER_ADV_REPORT_IND, truncated, not enough advRport buffers"); } else { diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave.c index e9c422f9c61..6d83d422120 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave_ae.c index cb639890eb3..17f3b8c0029 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -32,8 +33,6 @@ * * \param pBuf Packed packet buffer. * \param pEvt Advertising set terminated indication data. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackAdvSetTermEvt(uint8_t *pBuf, const LlAdvSetTermInd_t *pEvt) @@ -51,8 +50,6 @@ static void lhciPackAdvSetTermEvt(uint8_t *pBuf, const LlAdvSetTermInd_t *pEvt) * * \param pBuf Packed packet buffer. * \param pEvt Scan request received indication data. - * - * \return None. */ /*************************************************************************************************/ static void lhciPackScanReqRcvdEvt(uint8_t *pBuf, const LlScanReqRcvdInd_t *pEvt) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_master.c new file mode 100644 index 00000000000..f5e41fed740 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_master.c @@ -0,0 +1,183 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "ll_api.h" +#include "util/bstream.h" + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG Terminate Sync command complete packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt BIG terminate event data. + */ +/*************************************************************************************************/ +static void lhciPackCmdCompleteBigTerminateSync(uint8_t *pBuf, const LlBigTermSyncCnf_t *pEvt) +{ + UINT8_TO_BSTREAM(pBuf, pEvt->status); + UINT8_TO_BSTREAM(pBuf, pEvt->bigHandle); +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG create BIG Sync Established event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt BIG Sync Established event data. + */ +/*************************************************************************************************/ +static void lhciPackBigSyncEstEvt(uint8_t *pBuf, const LlBigSyncEstInd_t *pEvt) +{ + UINT8_TO_BSTREAM (pBuf, HCI_LE_BIG_SYNC_EST_EVT); + UINT8_TO_BSTREAM (pBuf, pEvt->status); + UINT8_TO_BSTREAM (pBuf, pEvt->bigHandle); + UINT24_TO_BSTREAM(pBuf, pEvt->transLatUsec); + UINT8_TO_BSTREAM (pBuf, pEvt->nse); + UINT8_TO_BSTREAM (pBuf, pEvt->bn); + UINT8_TO_BSTREAM (pBuf, pEvt->pto); + UINT8_TO_BSTREAM (pBuf, pEvt->irc); + UINT16_TO_BSTREAM(pBuf, pEvt->maxPdu); + UINT16_TO_BSTREAM(pBuf, pEvt->isoInterval); + UINT8_TO_BSTREAM (pBuf, pEvt->numBis); + for (unsigned int i = 0; i < pEvt->numBis; i++) + { + UINT16_TO_BSTREAM(pBuf, pEvt->bisHandle[i]); + } +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG Sync Lost event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Terminate BIG Complete event data. + */ +/*************************************************************************************************/ +static void lhciPackBigSyncLostEvt(uint8_t *pBuf, const LlBigSyncLostInd_t *pEvt) +{ + UINT8_TO_BSTREAM(pBuf, HCI_LE_BIG_SYNC_LOST_EVT); + UINT8_TO_BSTREAM(pBuf, pEvt->bigHandle); + UINT8_TO_BSTREAM(pBuf, pEvt->reason); +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIG Sync Lost event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Terminate BIG Complete event data. + */ +/*************************************************************************************************/ +static void lhciPackBigBigInfoAdvReportEvt(uint8_t *pBuf, const LlBigInfoAdvRptInd_t *pEvt) +{ + UINT8_TO_BSTREAM (pBuf, HCI_LE_BIG_INFO_ADV_REPORT_EVT); + UINT16_TO_BSTREAM(pBuf, pEvt->syncHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->numBis); + UINT8_TO_BSTREAM (pBuf, pEvt->nse); + UINT16_TO_BSTREAM(pBuf, pEvt->isoInterv); + UINT8_TO_BSTREAM (pBuf, pEvt->bn); + UINT8_TO_BSTREAM (pBuf, pEvt->pto); + UINT8_TO_BSTREAM (pBuf, pEvt->irc); + UINT16_TO_BSTREAM(pBuf, pEvt->maxPdu); + UINT24_TO_BSTREAM(pBuf, pEvt->sduInterv); + UINT16_TO_BSTREAM(pBuf, pEvt->maxSdu); + UINT8_TO_BSTREAM (pBuf, pEvt->phy); + UINT8_TO_BSTREAM (pBuf, pEvt->framing); + UINT8_TO_BSTREAM (pBuf, pEvt->encrypt); +} + +/*************************************************************************************************/ +/*! + * \brief LL BIS master event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciMstBisEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + case LL_BIG_TERM_SYNC_CNF: + if ((pEvtBuf = lhciAllocEvt(HCI_CMD_CMPL_EVT, HCI_LEN_CMD_CMPL + LHCI_LEN_LE_BIG_TERMINATE_SYNC)) != NULL) + { + uint8_t *pBuf = pEvtBuf; + pBuf += LhciPackCmdCompleteEvt(pBuf, HCI_OPCODE_LE_BIG_TERMINATE_SYNC); + lhciPackCmdCompleteBigTerminateSync(pBuf, &pEvt->bigTermSyncCnf); + } + break; + + case LL_BIG_SYNC_EST_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_BIG_SYNC_EST_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_BIG_SYNC_EST(pEvt->bigSyncEstInd.numBis))) != NULL) + { + lhciPackBigSyncEstEvt(pEvtBuf, &pEvt->bigSyncEstInd); + } + } + break; + + case LL_BIG_SYNC_LOST_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_BIG_SYNC_LOST_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_BIG_SYNC_LOST)) != NULL) + { + lhciPackBigSyncLostEvt(pEvtBuf, &pEvt->bigSyncLostInd); + } + } + break; + + case LL_BIG_INFO_ADV_REPORT_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_BIG_INFO_ADV_RPT_EVT) << LHCI_BYTE_TO_BITS(4))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_BIG_INFO_ADV_REPORT)) != NULL) + { + lhciPackBigBigInfoAdvReportEvt(pEvtBuf, &pEvt->bigInfoInd); + } + } + break; + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_slave.c new file mode 100644 index 00000000000..0aef969937e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_bis_slave.c @@ -0,0 +1,129 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "ll_api.h" +#include "util/bstream.h" + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a BIS create BIG complete event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Generate BIS create BIG complete data. + */ +/*************************************************************************************************/ +static void lhciPackCreateBigCnfEvt(uint8_t *pBuf, const LlCreateBigCnf_t *pEvt) +{ + UINT8_TO_BSTREAM (pBuf, HCI_LE_CREATE_BIG_CMPL_EVT); + UINT8_TO_BSTREAM (pBuf, pEvt->status); + UINT8_TO_BSTREAM (pBuf, pEvt->bigHandle); + UINT24_TO_BSTREAM(pBuf, pEvt->syncDelayUsec); + UINT24_TO_BSTREAM(pBuf, pEvt->transLatUsec); + UINT8_TO_BSTREAM (pBuf, pEvt->phy); + UINT8_TO_BSTREAM (pBuf, pEvt->nse); + UINT8_TO_BSTREAM (pBuf, pEvt->bn); + UINT8_TO_BSTREAM (pBuf, pEvt->pto); + UINT8_TO_BSTREAM (pBuf, pEvt->irc); + UINT16_TO_BSTREAM(pBuf, pEvt->maxPdu); + UINT16_TO_BSTREAM(pBuf, pEvt->isoInterval); + UINT8_TO_BSTREAM (pBuf, pEvt->numBis); + for (unsigned int i = 0; i < pEvt->numBis; i++) + { + UINT16_TO_BSTREAM(pBuf, pEvt->bisHandle[i]); + } +} + +/*************************************************************************************************/ +/*! + * \brief Pack a BIS terminate BIG complete event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Generate BIS create BIG complete data. + */ +/*************************************************************************************************/ +static void lhciPackTerminateBigCnfEvt(uint8_t *pBuf, const LlTerminateBigInd_t *pEvt) +{ + UINT8_TO_BSTREAM(pBuf, HCI_LE_TERMINATE_BIG_CMPL_EVT); + UINT8_TO_BSTREAM(pBuf, pEvt->bigHandle); + UINT8_TO_BSTREAM(pBuf, pEvt->reason); +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief LL BIS slave event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciSlvBigEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + case LL_CREATE_BIG_CNF: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_CREATE_BIG_CMPL_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_CREATE_BIG_CMPL(pEvt->createBigCnf.numBis))) != NULL) + { + lhciPackCreateBigCnfEvt(pEvtBuf, &pEvt->createBigCnf); + } + } + break; + + case LL_TERM_BIG_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_TERMINATE_BIG_CMPL_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_TERMINATE_BIG_CMPL)) != NULL) + { + lhciPackTerminateBigCnfEvt(pEvtBuf, &pEvt->termBigInd); + } + } + break; + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_master.c new file mode 100644 index 00000000000..953d0072253 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_master.c @@ -0,0 +1,115 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#include "lhci_int.h" +#include "chci_api.h" +#include "hci_defs.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a CIS established event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt CIS established event data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackCisEstEvt(uint8_t *pBuf, const LlCisEstInd_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_CIS_EST; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_CIS_EST_EVT); + UINT8_TO_BSTREAM (pBuf, pEvt->status); + UINT16_TO_BSTREAM (pBuf, pEvt->cisHandle); + UINT24_TO_BSTREAM (pBuf, pEvt->cigSyncDelayUsec); + UINT24_TO_BSTREAM (pBuf, pEvt->cisSyncDelayUsec); + UINT24_TO_BSTREAM (pBuf, pEvt->transLatUsecMToS); + UINT24_TO_BSTREAM (pBuf, pEvt->transLatUsecSToM); + UINT8_TO_BSTREAM (pBuf, pEvt->phyMToS); + UINT8_TO_BSTREAM (pBuf, pEvt->phySToM); + UINT8_TO_BSTREAM (pBuf, pEvt->nse); + UINT8_TO_BSTREAM (pBuf, pEvt->bnMToS); + UINT8_TO_BSTREAM (pBuf, pEvt->bnSToM); + UINT8_TO_BSTREAM (pBuf, pEvt->ftMToS); + UINT8_TO_BSTREAM (pBuf, pEvt->ftSToM); + UINT16_TO_BSTREAM (pBuf, pEvt->maxPduMToS); + UINT16_TO_BSTREAM (pBuf, pEvt->maxPduSToM); + UINT16_TO_BSTREAM (pBuf, pEvt->isoInterval); + + return len; +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief LL CIS master event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciMstCisEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + case LL_CIS_EST_IND: + { + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_CIS_EST_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_CIS_EST)) != NULL) + { + lhciPackCisEstEvt(pEvtBuf, &pEvt->cisEstInd); + } + } + break; + } + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_slave.c new file mode 100644 index 00000000000..45cb4770006 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_cis_slave.c @@ -0,0 +1,101 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "lctr_api_cis_slave.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "wsf_msg.h" +#include "wsf_os.h" +#include "util/bstream.h" + +/************************************************************************************************** + Local Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Pack a CIS request event packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Generate CIS request data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackCisReqEvt(uint8_t *pBuf, const LlCisReqInd_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_CIS_REQ; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_CIS_REQ_EVT); + UINT16_TO_BSTREAM (pBuf, pEvt->aclHandle); + UINT16_TO_BSTREAM(pBuf, pEvt->cisHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->cigId); + UINT8_TO_BSTREAM (pBuf, pEvt->cisId); + + return len; +} + +/************************************************************************************************** + External Functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief LL CIS slave event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciSlvCisEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + case LL_CIS_REQ_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_CIS_REQ_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_CIS_REQ)) != NULL) + { + lhciPackCisReqEvt(pEvtBuf, &pEvt->cisReqInd); + } + } + break; + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn.c index 94d7167223b..8929c53ac2e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -39,14 +40,13 @@ * \return Packet length. */ /*************************************************************************************************/ -static uint8_t lhciPackNumCompPktsEvt(uint8_t *pBuf, uint16_t connHandle, uint8_t numPkts) +static uint8_t lhciPackNumCompPktsEvt(uint8_t *pBuf, uint16_t connHandle, uint16_t numPkts) { - const uint8_t len = HCI_LEN_NUM_CMPL_PKTS; - uint16_t numPkts_u16 = numPkts; + const uint8_t len = HCI_LEN_NUM_CMPL_PKTS(1); UINT8_TO_BSTREAM (pBuf, 1); UINT16_TO_BSTREAM(pBuf, connHandle); - UINT16_TO_BSTREAM(pBuf, numPkts_u16); + UINT16_TO_BSTREAM(pBuf, numPkts); return len; } @@ -251,14 +251,60 @@ static uint8_t lhciPackReqPeerScaCompleteEvt(uint8_t *pBuf, const LlPeerScaCnf_t return len; } +/*************************************************************************************************/ +/*! + * \brief Power report event handler. + * + * \param pBuf Packed packet buffer. + * \param pEvt Power report indication data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackPowerReportEvt(uint8_t *pBuf, const LlPowerReportInd_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_POWER_REPORT; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_POWER_REPORT_EVT); + UINT8_TO_BSTREAM (pBuf, pEvt->status) + UINT16_TO_BSTREAM(pBuf, pEvt->connHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->reason); + UINT8_TO_BSTREAM (pBuf, pEvt->phy); + UINT8_TO_BSTREAM (pBuf, pEvt->txPower); + UINT8_TO_BSTREAM (pBuf, pEvt->txPowerLimits); + UINT8_TO_BSTREAM (pBuf, pEvt->delta); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Path loss event handler. + * + * \param pBuf Packed packet buffer. + * \param pEvt Path loss event data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackPathLossEvt(uint8_t *pBuf, const LlPathLossThresholdEvt_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_PATH_LOSS_ZONE; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_PATH_LOSS_REPORT_EVT); + UINT16_TO_BSTREAM(pBuf, pEvt->connHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->curPathLoss); + UINT8_TO_BSTREAM (pBuf, pEvt->zoneEntered); + + return len; +} + /*************************************************************************************************/ /*! * \brief LL ACL send complete event handler. * * \param handle Connection handle. * \param numBufs Number of buffers. - * - * \return None. */ /*************************************************************************************************/ void lhciAclSendComplete(uint16_t handle, uint8_t numBufs) @@ -267,7 +313,7 @@ void lhciAclSendComplete(uint16_t handle, uint8_t numBufs) { uint8_t *pEvtBuf; - if ((pEvtBuf = lhciAllocEvt(HCI_NUM_CMPL_PKTS_EVT, HCI_LEN_NUM_CMPL_PKTS)) != NULL) + if ((pEvtBuf = lhciAllocEvt(HCI_NUM_CMPL_PKTS_EVT, HCI_LEN_NUM_CMPL_PKTS(1))) != NULL) { lhciPackNumCompPktsEvt(pEvtBuf, handle, numBufs); lhciSendEvt(pEvtBuf); @@ -336,8 +382,6 @@ uint8_t *lhciRecvAcl(void) * * \param handle Connection handle. * \param numBufs Number of buffers. - * - * \return None. */ /*************************************************************************************************/ void lhciAclRecvPending(uint16_t handle, uint8_t numBufs) @@ -451,6 +495,26 @@ bool_t lhciConnEncodeEvtPkt(LlEvt_t *pEvt) } } break; + case LL_TX_POWER_REPORTING_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_TX_POWER_REPORT_EVT) << LHCI_BYTE_TO_BITS(4))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_POWER_REPORT)) != NULL) + { + lhciPackPowerReportEvt(pEvtBuf, &pEvt->powerRptInd); + } + } + break; + case LL_PATH_LOSS_REPORTING_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_PATH_LOSS_REPORT_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_PATH_LOSS_ZONE)) != NULL) + { + lhciPackPathLossEvt(pEvtBuf, &pEvt->pathLossEvt); + } + } + break; default: break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_cs2.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_cs2.c index 632db665eeb..1423cd17c04 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_cs2.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_cs2.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_master.c index 2f920b01456..8217178c988 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_priv.c index 3c76ec5fb7e..22841e47534 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_conn_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_master.c index e568b367246..2031d5c2102 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_slave.c index 5cfdd10705e..15336b9e03c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_iso.c new file mode 100644 index 00000000000..24011075e76 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_iso.c @@ -0,0 +1,203 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "chci_api.h" +#include "hci_defs.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Pack a number of completed packets event packet. + * + * \param pBuf Packed packet buffer. + * \param numHandles Number of handles. + * \param pHandle Array of CIS or BIS handle. + * \param pNumPkts Array of number of completed packets. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackNumCompPktsEvt(uint8_t *pBuf, uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts) +{ + const uint8_t len = HCI_LEN_NUM_CMPL_PKTS(numHandles); + + UINT8_TO_BSTREAM (pBuf, numHandles); + + for (unsigned int i = 0; i < numHandles; i++) + { + UINT16_TO_BSTREAM(pBuf, pHandle[i]); + UINT16_TO_BSTREAM(pBuf, pNumPkts[i]); + } + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Free the received ISO data for test Rx. + * + * \param pIsoData ISO data buffer. + */ +/*************************************************************************************************/ +static void lhciFreeRcvdIsoData(uint8_t *pIsoData) +{ + WsfMsgFree(pIsoData); + LlRecvIsoDataComplete(1); +} + +/*************************************************************************************************/ +/*! + * \brief LL ISO send complete event handler. + * + * \param numHandles Number of handles. + * \param pHandle Array of CIS or BIS handle. + * \param pNumPkts Array of number of completed packets. + */ +/*************************************************************************************************/ +void lhciIsoSendComplete(uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts) +{ + uint8_t *pEvtBuf; + + if ((pEvtBuf = lhciAllocEvt(HCI_NUM_CMPL_PKTS_EVT, HCI_LEN_NUM_CMPL_PKTS(numHandles))) != NULL) + { + lhciPackNumCompPktsEvt(pEvtBuf, numHandles, pHandle, pNumPkts); + + lhciSendEvt(pEvtBuf); + } +} + +/*************************************************************************************************/ +/*! + * \brief Sink LL ACL. + * + * \param pBuf Buffer to sink. + * + * \return TRUE if buffer sink. + */ +/*************************************************************************************************/ +static bool_t lhciSinkIso(uint8_t *pBuf) +{ + if (lhciIsoCb.recvIsoSink) + { + uint8_t len; + + len = pBuf[2]; + lhciIsoCb.recvIsoPktCnt++; + lhciIsoCb.recvIsoOctetCnt += len; + + WsfMsgFree(pBuf); + LlRecvIsoDataComplete(1); + return TRUE; + } + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Receive LL ISO. + * + * \return Pointer to buffer for transport. + */ +/*************************************************************************************************/ +uint8_t *lhciRecvIso(void) +{ + uint8_t *pIsoData; + + if ((pIsoData = LlRecvIsoData()) != NULL) + { + if (!lhciSinkIso(pIsoData)) + { + return pIsoData; + } + } + + return NULL; +} + +/*************************************************************************************************/ +/*! + * \brief LL ISO receive pending event handler. + * + * \param numHandles Number of handles. + * \param pHandle Array of CIS or BIS handle. + * \param pNumPkts Array of number of pending packets. + */ +/*************************************************************************************************/ +void lhciIsoRecvPending(uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts) +{ + uint8_t *pIsoData; + + if (lhciIsoCb.isoRxTest == TRUE) + { + if ((pIsoData = LlRecvIsoData()) != NULL) + { + lhciFreeRcvdIsoData(pIsoData); + return; + } + } + else + { + if (lhciIsoCb.recvIsoSink && ((pIsoData = LlRecvIsoData()) != NULL)) + { + lhciSinkIso(pIsoData); + return; + } + } + + ChciTrNeedsService(CHCI_TR_PROT_BLE); +} + +/*************************************************************************************************/ +/*! + * \brief LL ISO event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciIsoEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} + diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_pc.c new file mode 100644 index 00000000000..3c4c5c57091 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_pc.c @@ -0,0 +1,124 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief LL HCI event module implementation file. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "chci_api.h" +#include "hci_defs.h" +#include "wsf_msg.h" +#include "util/bstream.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Power report event handler. + * + * \param pBuf Packed packet buffer. + * \param pEvt Power report indication data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackPowerReportEvt(uint8_t *pBuf, const LlPowerReportInd_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_POWER_REPORT; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_POWER_REPORT_EVT); + UINT8_TO_BSTREAM (pBuf, pEvt->status) + UINT16_TO_BSTREAM(pBuf, pEvt->connHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->reason); + UINT8_TO_BSTREAM (pBuf, pEvt->phy); + UINT8_TO_BSTREAM (pBuf, pEvt->txPower); + UINT8_TO_BSTREAM (pBuf, pEvt->txPowerLimits); + UINT8_TO_BSTREAM (pBuf, pEvt->delta); + + return len; +} + +/*************************************************************************************************/ +/*! + * \brief Path loss event handler. + * + * \param pBuf Packed packet buffer. + * \param pEvt Path loss event data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciPackPathLossEvt(uint8_t *pBuf, const LlPathLossThresholdEvt_t *pEvt) +{ + const uint8_t len = HCI_LEN_LE_PATH_LOSS_ZONE; + + UINT8_TO_BSTREAM (pBuf, HCI_LE_PATH_LOSS_REPORT_EVT); + UINT16_TO_BSTREAM(pBuf, pEvt->connHandle); + UINT8_TO_BSTREAM (pBuf, pEvt->curPathLoss); + UINT8_TO_BSTREAM (pBuf, pEvt->zoneEntered); + + return len; +} +/*************************************************************************************************/ +/*! + * \brief LL connection event handler. + * + * \param pEvt Buffer containing LL event. + * + * \return TRUE if event handled, FALSE otherwise. + */ +/*************************************************************************************************/ +bool_t lhciPclEncodeEvtPkt(LlEvt_t *pEvt) +{ + uint8_t *pEvtBuf = NULL; + + switch (pEvt->hdr.event) + { + case LL_TX_POWER_REPORTING_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_TX_POWER_REPORT_EVT) << LHCI_BYTE_TO_BITS(4))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_POWER_REPORT)) != NULL) + { + lhciPackPowerReportEvt(pEvtBuf, &pEvt->powerRptInd); + } + } + break; + case LL_PATH_LOSS_REPORTING_IND: + if ((lhciCb.leEvtMsk & ((uint64_t)(HCI_EVT_MASK_LE_PATH_LOSS_REPORT_EVT) << LHCI_BYTE_TO_BITS(3))) && + (lhciCb.evtMsk & ((uint64_t)(HCI_EVT_MASK_LE_META) << LHCI_BYTE_TO_BITS(7)))) + { + if ((pEvtBuf = lhciAllocEvt(HCI_LE_META_EVT, HCI_LEN_LE_PATH_LOSS_ZONE)) != NULL) + { + lhciPackPathLossEvt(pEvtBuf, &pEvt->pathLossEvt); + } + } + break; + + default: + break; + } + + if (pEvtBuf) + { + lhciSendEvt(pEvtBuf); + return TRUE; + } + + return FALSE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_phy.c index fff4ba59a50..5ef331bcce1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_sc.c index b6901db08d3..e0cd3987c3d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI event module implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_vs.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_vs.c index 733542406cf..95a33699911 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_vs.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_evt_vs.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Vendor specific HCI event module implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Vendor specific HCI event module implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -25,7 +26,9 @@ #include "hci_defs.h" #include "wsf_msg.h" #include "util/bstream.h" +#include "bb_ble_api_op.h" #include +#include "bb_ble_sniffer_api.h" /************************************************************************************************** Macros @@ -33,10 +36,127 @@ /* Note: Arm Ltd. vendor specific subevent code is 0xFFF0-0xFFFF. */ -#define LHCI_OPCODE_VS_SUBEVT_TRACE_MSG 0xFFF0 /*!< Trace message event. */ -#define LHCI_OPCODE_VS_SUBEVT_SCAN_REPORT 0xFFF1 /*!< Scan report event. */ +#define LHCI_OPCODE_VS_SUBEVT_TRACE_MSG 0xFFF0 /*!< Trace message event. */ +#define LHCI_OPCODE_VS_SUBEVT_SCAN_REPORT 0xFFF1 /*!< Scan report event. */ +#define LHCI_OPCODE_VS_SUBEVT_PACKET_REPORT 0xFFF2 /*!< Packet report event from sniffer. */ +#define LHCI_OPCODE_VS_SUBEVT_ISO_EVT_CMPL 0xFFF3 /*!< ISO Event complete event. */ #define LHCI_LEN_VS_SUBEVT_SCAN_REPORT 13 /*!< Scan report event length. */ +#define LHCI_LEN_VS_SUBEVT_ISO_EVT_CMPL 8 /*!< ISO Event complete length. */ + +#if (BB_SNIFFER_ENABLED == TRUE) +/*************************************************************************************************/ +/*! + * \brief Send a packet report event. + * + * \param pBuf Message. + * + * \return TRUE if successful, FALSE otherwise. + */ +/*************************************************************************************************/ +static bool_t LhciVsEncodeSnifferPktEvtPkt(BbBleSnifferPkt_t *pPktData) +{ + uint8_t *pEvtBuf; + uint8_t *pPkt = lhciAllocEvt(HCI_VENDOR_SPEC_EVT, LHCI_LEN_VS_EVT + BB_SNIFFER_MAX_PKT_SIZE); + + if (pPkt == NULL) + { + return FALSE; + } + + pEvtBuf = pPkt; + pEvtBuf += lhciPackVsEvt(pEvtBuf, LHCI_OPCODE_VS_SUBEVT_PACKET_REPORT); + + /* Pack metadata. */ + BbBleSnifferMeta_t meta = pPktData->pktType.meta; + UINT8_TO_BSTREAM(pEvtBuf, meta.type); + UINT8_TO_BSTREAM(pEvtBuf, meta.status); + UINT8_TO_BSTREAM(pEvtBuf, meta.state); + UINT32_TO_BSTREAM(pEvtBuf, meta.timeStamp); + UINT8_TO_BSTREAM(pEvtBuf, meta.rssi); + + /* Pack channelization metadata. */ + PalBbBleChan_t chan = meta.chan; + UINT8_TO_BSTREAM(pEvtBuf, chan.opType); + UINT8_TO_BSTREAM(pEvtBuf, chan.chanIdx); + UINT8_TO_BSTREAM(pEvtBuf, chan.txPower); + UINT32_TO_BSTREAM(pEvtBuf, chan.accAddr); + UINT24_TO_BSTREAM(pEvtBuf, chan.crcInit); + UINT8_TO_BSTREAM(pEvtBuf, chan.txPhy); + UINT8_TO_BSTREAM(pEvtBuf, chan.rxPhy); + UINT8_TO_BSTREAM(pEvtBuf, chan.initTxPhyOptions); + UINT8_TO_BSTREAM(pEvtBuf, chan.tifsTxPhyOptions); + UINT8_TO_BSTREAM(pEvtBuf, chan.peerTxStableModIdx); + UINT8_TO_BSTREAM(pEvtBuf, chan.peerRxStableModIdx); + + /* Pack data based on packet. */ + switch (chan.opType) + { + case BB_BLE_OP_MST_ADV_EVENT: + case BB_BLE_OP_SLV_ADV_EVENT: + case BB_BLE_OP_MST_AUX_ADV_EVENT: + case BB_BLE_OP_SLV_AUX_ADV_EVENT: + case BB_BLE_OP_MST_PER_SCAN_EVENT: + case BB_BLE_OP_SLV_PER_ADV_EVENT: + memcpy(pEvtBuf, pPktData->pktType.advPkt.hdr, LL_ADV_HDR_LEN); + break; + + case BB_BLE_OP_MST_CONN_EVENT: + case BB_BLE_OP_SLV_CONN_EVENT: + memcpy(pEvtBuf, pPktData->pktType.dataPkt.hdr, LL_DATA_HDR_MAX_LEN); + break; + + default: + break; + } + + lhciSendEvt(pPkt); + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Handle a received packet. + * + * \return TRUE if packets still remain. FALSE if not. + */ +/*************************************************************************************************/ +bool_t LhciSnifferHandler(void) +{ + BbBleSnifferHciCtx_t * pHci = &bbSnifferCtx.outputCtx.hci; + if ((bbSnifferCtx.enabled == FALSE) || + (pHci->bufIdx == 0)) + { + return FALSE; + } + + BbBleSnifferPkt_t * pPktData = &pHci->pktBuf[--pHci->bufIdx]; + LhciVsEncodeSnifferPktEvtPkt(pPktData); + + return pHci->bufIdx == 0; +} +#endif + +/*************************************************************************************************/ +/*! + * \brief Pack a scan report packet. + * + * \param pBuf Packed packet buffer. + * \param pEvt Scan report data. + * + * \return Packet length. + */ +/*************************************************************************************************/ +static uint8_t lhciVsPackScanReportEvt(uint8_t *pBuf, const LlScanReportInd_t *pEvt) +{ + const uint8_t len = LHCI_LEN_VS_SUBEVT_SCAN_REPORT; + + UINT8_TO_BSTREAM(pBuf, pEvt->peerAddrType); + BDA64_TO_BSTREAM(pBuf, pEvt->peerAddr); + BDA64_TO_BSTREAM(pBuf, pEvt->peerRpa); + + return len; +} /*************************************************************************************************/ /*! @@ -86,27 +206,6 @@ bool_t LhciVsEncodeTraceMsgEvtPkt(const uint8_t *pBuf, uint32_t len) return TRUE; } -/*************************************************************************************************/ -/*! - * \brief Pack a scan report packet. - * - * \param pBuf Packed packet buffer. - * \param pEvt Scan report data. - * - * \return Packet length. - */ -/*************************************************************************************************/ -static uint8_t lhciVsPackScanReportEvt(uint8_t *pBuf, const LlScanReportInd_t *pEvt) -{ - const uint8_t len = LHCI_LEN_VS_SUBEVT_SCAN_REPORT; - - UINT8_TO_BSTREAM(pBuf, pEvt->peerAddrType); - BDA64_TO_BSTREAM(pBuf, pEvt->peerAddr); - BDA64_TO_BSTREAM(pBuf, pEvt->peerRpa); - - return len; -} - /*************************************************************************************************/ /*! * \brief LL slave VS event handler. @@ -132,6 +231,18 @@ bool_t lhciSlvVsStdEncodeEvtPkt(LlEvt_t *pEvt) } break; + case LL_ISO_EVT_CMPL_IND: + /* No need to check the event mask; LL should not generate this event without the event masked. */ + if ((pEvtBuf = lhciAllocEvt(HCI_VENDOR_SPEC_EVT, LHCI_LEN_VS_EVT + LHCI_LEN_VS_SUBEVT_ISO_EVT_CMPL)) != NULL) + { + uint8_t *pBuf = pEvtBuf; + pBuf += LhciPackVsEvt(pBuf, LHCI_OPCODE_VS_SUBEVT_ISO_EVT_CMPL); + UINT8_TO_BSTREAM(pBuf, pEvt->isoEvtCmplInd.handle); + pBuf += 3; /* padding */ + UINT32_TO_BSTREAM(pBuf, pEvt->isoEvtCmplInd.evtCtr); + } + break; + default: break; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init.c index 78e8087f3c2..2bd21d6de3f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -31,8 +32,6 @@ * * \param handlerId WSF handler ID. * - * \return None. - * * This function initializes the LL HCI subsystem. It is typically called once upon system * initialization. */ @@ -56,8 +55,6 @@ void LhciHandlerInit(wsfHandlerId_t handlerId) * \brief Initialize VS extended command decoder. * * \param decodeCmd Command decoder. - * - * \return None. */ /*************************************************************************************************/ void LhciVsExtInit(lhciCmdHandler_t decodeCmd) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master.c index d9ff608a09d..d5a1052e488 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for master mode. * - * \return None. - * * This function initializes the LL HCI subsystem for master commands. It is typically called * once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master_ae.c index 41b544f4db4..d982c180779 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -28,8 +29,6 @@ /*! * \brief Initialize LL HCI subsystem for master mode. * - * \return None. - * * This function initializes the LL HCI subsystem for master commands. It is typically called * once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_priv.c index 118f4c8a0b0..9faea59fc93 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for privacy. * - * \return None. - * * This function initializes the LL HCI subsystem for LE Privacy 1.2. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave.c index 014e57cd9d4..ecf4c8a84e8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for slave mode. * - * \return None. - * * This function initializes the LL HCI subsystem for slave commands. It is typically called * once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave_ae.c index 78e9952a038..7852308e221 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for slave mode. * - * \return None. - * * This function initializes the LL HCI subsystem for slave commands. It is typically called * once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_master.c new file mode 100644 index 00000000000..bace6fdd099 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_master.c @@ -0,0 +1,40 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for BIS slave mode. + * + * This function initializes the LL HCI subsystem for BIS slave commands. It is typically called + * once upon system initialization. + */ +/*************************************************************************************************/ +void LhciBisMasterInit(void) +{ + lhciCmdTbl[LHCI_MSG_BIS_MST] = lhciMstBisDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_BIS_MST] = lhciMstBisEncodeEvtPkt; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_slave.c new file mode 100644 index 00000000000..f9521c8f4eb --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_bis_slave.c @@ -0,0 +1,40 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for BIS slave mode. + * + * This function initializes the LL HCI subsystem for BIS slave commands. It is typically called + * once upon system initialization. + */ +/*************************************************************************************************/ +void LhciBisSlaveInit(void) +{ + lhciCmdTbl[LHCI_MSG_BIS_SLV] = lhciSlvBisDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_BIS_SLV] = lhciSlvBigEncodeEvtPkt; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_master.c new file mode 100644 index 00000000000..1b1e529d621 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_master.c @@ -0,0 +1,40 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for CIS master mode. + * + * This function initializes the LL HCI subsystem for CIS master commands. It is typically called + * once upon system initialization. + */ +/*************************************************************************************************/ +void LhciCisMasterInit(void) +{ + lhciCmdTbl[LHCI_MSG_CIS_MST] = lhciMstCisDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_CIS_MST] = lhciMstCisEncodeEvtPkt; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_slave.c new file mode 100644 index 00000000000..c33329c2c1c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_cis_slave.c @@ -0,0 +1,40 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for CIS slave mode. + * + * This function initializes the LL HCI subsystem for CIS slave commands. It is typically called + * once upon system initialization. + */ +/*************************************************************************************************/ +void LhciCisSlaveInit(void) +{ + lhciCmdTbl[LHCI_MSG_CIS_SLV] = lhciSlvCisDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_CIS_SLV] = lhciSlvCisEncodeEvtPkt; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn.c index 1213ada0d2a..3bad47d051f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for connections. * - * \return None. - * * This function initializes the LL HCI subsystem for ACL data exchanges. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_cs2.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_cs2.c index 4e9f26adfc5..7175a0d17eb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_cs2.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_cs2.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for channel selection 2. * - * \return None. - * * This function initializes the LL HCI subsystem for channel selection 2.. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master.c index 9647e002d71..f09b3faa0ac 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for master connections. * - * \return None. - * * This function initializes the LL HCI subsystem for ACL data exchanges. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master_ae.c index bdbdd46eb3b..add8aacd910 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for master connections. * - * \return None. - * * This function initializes the LL HCI subsystem for ACL data exchanges. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_priv.c index 7aed705f285..28d6da47152 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_conn_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for privacy (connections). * - * \return None. - * * This function initializes the LL HCI subsystem for LE Privacy 1.2. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_master.c index fa02e5a296a..c88bbdb811c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for master encryption mode. * - * \return None. - * * This function initializes the LL HCI subsystem for master commands. It is typically called * once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_slave.c index 16fe852ab40..e37b6f96599 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for slave encryption mode. * - * \return None. - * * This function initializes the LL HCI subsystem for slave encryption commands. It is typically * called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_iso.c new file mode 100644 index 00000000000..6d4ee337ffa --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_iso.c @@ -0,0 +1,69 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "chci_api.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI handler including ISO feature. + * + * \param handlerId WSF handler ID. + * + * This function initializes the LL HCI subsystem. It is typically called once upon system + * initialization. + */ +/*************************************************************************************************/ +void LhciIsoHandlerInit(wsfHandlerId_t handlerId) +{ + ChciTrSetCbacks(CHCI_TR_PROT_BLE, lhciRecv, lhciSendComplete, lhciService); + ChciTrSetSendHwErrorCback(lhciSendHwError); + + memset(&lhciPersistCb, 0, sizeof(lhciPersistCb)); + lhciPersistCb.handlerId = handlerId; + memset(&lhciCb, 0, sizeof(lhciCb)); + + LlEvtRegister(lhciLlEvtHandler); + + lhciReset(); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for isochornous. + * + * This function initializes the LL HCI subsystem for ISO data exchanges. It is typically + * called once upon system initialization. + */ +/*************************************************************************************************/ +void LhciIsoInit(void) +{ + LlIsoRegister(lhciIsoSendComplete, lhciIsoRecvPending); + + lhciServiceIso = lhciRecvIso; + + lhciCmdTbl[LHCI_MSG_ISO] = lhciIsoDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_ISO] = lhciIsoEncodeEvtPkt; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_past.c index 760b729943b..f6cac4cf5d7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -28,8 +29,6 @@ /*! * \brief Initialize LL HCI subsystem for PAST(Periodic advertising sync transfer) features. * - * \return None. - * * This function initializes the LL HCI subsystem for PAST features commands. It is * typically called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_pc.c new file mode 100644 index 00000000000..d365a9d2dba --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_pc.c @@ -0,0 +1,38 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "lhci_api.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize LL HCI subsystem for Power control. + */ +/*************************************************************************************************/ +void LhciPowerControlInit(void) +{ + if (!lhciCmdTbl[LHCI_MSG_PC]) + { + lhciCmdTbl[LHCI_MSG_PC] = lhciPclDecodeCmdPkt; + lhciEvtTbl[LHCI_MSG_PC] = lhciPclEncodeEvtPkt; + } +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_phy.c index fbf9677710b..b266a779f80 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for PHY features. * - * \return None. - * * This function initializes the LL HCI subsystem for PHY features commands. It is * typically called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_sc.c index 5defba4d400..93f87922750 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_init_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL HCI subsystem for secure connections. * - * \return None. - * * This function initializes the LL HCI subsystem for secure connections commands. It is * typically called once upon system initialization. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_int.h index 7efadec4109..f0f91165e00 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_int.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_int.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief LL HCI main module interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief LL HCI main module interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -137,18 +138,31 @@ extern "C" { #define LHCI_LEN_LE_SET_PER_ADV_RCV_ENABLE 1 /*!< LE set periodic advertising receive enable command complete event length. */ #define LHCI_LEN_LE_PER_ADV_SYNC_TRANSFER 3 /*!< LE periodic advertising sync transfer command complete event length. */ #define LHCI_LEN_LE_PER_ADV_SET_INFO_TRANSFER 3 /*!< LE periodic advertising set info transfer command complete event length. */ -#define LHCI_LEN_LE_SET_PAST_PARAM 1 /*!< LE set periodic advertising sync transfer parameters command complete event length. */ +#define LHCI_LEN_LE_SET_PAST_PARAM 3 /*!< LE set periodic advertising sync transfer parameters command complete event length. */ #define LHCI_LEN_LE_SET_DEFAULT_PAST_PARAM 1 /*!< LE set default periodic advertising sync transfer parameters command complete event length. */ #define LHCI_LEN_LE_MODIFY_SCA_EVT 1 /*!< LE Modify sleep clock accuracy event length. */ -/* New in version Milan */ -#define LHCI_LEN_LE_READ_ISO_BUF_SIZE 4 /*!< LE read ISO buffer size command complete event length. */ +/* New in version 5.2 */ +#define LHCI_LEN_LE_READ_BUF_SIZE_V2 7 /*!< LE read ISO buffer size command complete event length. */ +#define LHCI_LEN_LE_READ_TX_SYNC 12 /*!< LE read ISO Tx sync. */ #define LHCI_LEN_LE_REMOVE_CIG 1 /*!< LE remove CIG. */ #define LHCI_LEN_LE_REJECT_CIS_REQ 1 /*!< LE reject CIS request. */ -#define LHCI_LEN_LE_SETUP_ISO_DATA_PATH 1 /*!< LE setup ISO data path. */ -#define LHCI_LEN_LE_REMOVE_ISO_DATA_PATH 1 /*!< LE remove ISO data path. */ +#define LHCI_LEN_LE_BIG_TERMINATE_SYNC 2 /*!< LE BIG terminate sync. */ +#define LHCI_LEN_LE_SETUP_ISO_DATA_PATH 3 /*!< LE setup ISO data path. */ +#define LHCI_LEN_LE_REMOVE_ISO_DATA_PATH 3 /*!< LE remove ISO data path. */ #define LHCI_LEN_LE_ISO_TX_TEST 1 /*!< LE ISO Tx Test. */ #define LHCI_LEN_LE_ISO_RX_TEST 1 /*!< LE ISO Rx Test. */ -#define LHCI_LEN_LE_ISO_READ_TEST_COUNTER 13 /*!< LE ISO read test counter. */ +#define LHCI_LEN_LE_ISO_READ_TEST_COUNTER 15 /*!< LE ISO read test counter. */ +#define LHCI_LEN_LE_ISO_TEST_END 15 /*!< LE ISO test end. */ +#define LHCI_LEN_LE_SET_HOST_FEATURE 1 /*!< LE Set Host Feature. */ +#define LHCI_LEN_LE_READ_ISO_LINK_QUAL 31 /*!< LE Read ISO link quality. */ +#define LHCI_LEN_LE_READ_ENH_TX_POWER_EVT 6 /*!< LE Read enhanced TX power. */ +#define LHCI_LEN_LE_SET_TX_POWER_REPORT_EVT 3 /*!< LE Set transmit power reporting enable event. */ +#define LHCI_LEN_LE_SET_PATH_LOSS_REPORTING_PARAMS 3 /*!< LE Set path loss reporting parameters event. */ +#define LHCI_LEN_LE_SET_PATH_LOSS_REPORTING_ENABLE 3 /*!< LE Set path loss reporting enable event. */ +#define LHCI_LEN_CONFIG_DATA_PATH 1 /*!< Configure data path. */ +#define LHCI_LEN_READ_LOCAL_SUP_CODECS 3 /*!< Read local supported codecs. */ +#define LHCI_LEN_READ_LOCAL_SUP_CODEC_CAP 2 /*!< Read local supported codec configuration. */ +#define LHCI_LEN_READ_LOCAL_SUP_CONTROLLER_DLY 7 /*!< Read local supported controller delay. */ /*! \brief Mandatory event mask. */ #define LHCI_DEF_EVT_MASK UINT64_C(0x00001FFFFFFFFFFF); @@ -173,7 +187,7 @@ extern "C" { /*! \brief Indicate command status event shall be returned. */ #define LHCI_LEN_CMD_STATUS_EVT 0xFF -/* Cordio vendor specific OCF range is 0x3C0-0x3FF */ +/* Packetcraft vendor specific OCF range is 0x3C0-0x3FF */ #define LHCI_OPCODE_VS_SET_SCAN_CH_MAP HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E0) /*!< Set Scan Channel Map opcode. */ #define LHCI_OPCODE_VS_SET_EVENT_MASK HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E1) /*!< Set Vendor Specific Event Mask opcode. */ #define LHCI_OPCODE_VS_SET_RSRC_MGR_MODE HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E2) /*!< DEPRECATED. */ @@ -184,7 +198,7 @@ extern "C" { #define LHCI_OPCODE_VS_SET_CONN_OP_FLAGS HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E7) /*!< Set Connection Operational Flags opcode. */ #define LHCI_OPCODE_VS_SET_P256_PRIV_KEY HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E8) /*!< Set P-256 Private Key opcode. */ #define LHCI_OPCODE_VS_GET_PER_CHAN_MAP HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DE) /*!< Get channel map of periodic scan/adv. */ -#define LHCI_OPCODE_VS_SET_HCI_SUP_CMD HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DF) /*!< Set Hci supported commands. */ +#define LHCI_OPCODE_VS_SET_HCI_SUP_CMD HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DF) /*!< DEPRECATED. */ #define LHCI_OPCODE_VS_GET_ACL_TEST_REPORT HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3E9) /*!< Get ACL Test Report opcode. */ #define LHCI_OPCODE_VS_SET_LOCAL_MIN_USED_CHAN HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3EA) /*!< Set local minimum number of used channels. */ #define LHCI_OPCODE_VS_GET_PEER_MIN_USED_CHAN HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3EB) /*!< Get peer minimum number of used channels. */ @@ -200,6 +214,7 @@ extern "C" { #define LHCI_OPCODE_VS_SET_CHAN_MAP HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3F8) /*!< Set Channel Map opcode. */ #define LHCI_OPCODE_VS_SET_DIAG_MODE HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3F9) /*!< Set Diagnostic Mode opcode. */ +#define LHCI_OPCODE_VS_SET_SNIFFER_ENABLE HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3CD) /*!< Enable sniffer packet forwarding. */ #define LHCI_OPCODE_VS_GET_PDU_FILT_STATS HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3F4) /*!< Get PDU Filter Statistics opcode. */ #define LHCI_OPCODE_VS_GET_SYS_STATS HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3FA) /*!< Get Memory Statistics opcode. */ @@ -224,11 +239,13 @@ extern "C" { #define LHCI_OPCODE_VS_GET_AUX_SCAN_STATS HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DB) /*!< Get Auxiliary Scanning Statistics opcode. */ #define LHCI_OPCODE_VS_GET_PER_SCAN_STATS HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DC) /*!< Get Periodic Scanning Statistics opcode. */ +#define LHCI_OPCODE_VS_SET_CONN_PHY_TX_PWR HCI_OPCODE(HCI_OGF_VENDOR_SPEC, 0x3DD) /*!< Set Connection Phy Tx Power opcode. */ /* Vendor specific event masks. */ #define LHCI_VS_EVT_MASK_SCAN_REPORT_EVT 0x01 /*!< (Byte 0) VS event bit, scan report. */ #define LHCI_VS_EVT_MASK_DIAG_TRACE_EVT 0x02 /*!< (Byte 0) VS event bit, diagnostic tracing. */ +#define LHCI_VS_EVT_MASK_ISO_EVENT_CMPL_EVT 0x04 /*!< (Byte 0) VS event bit, ISO event complete. */ /************************************************************************************************** Data Types @@ -252,7 +269,10 @@ enum LHCI_MSG_PAST, /*!< Periodic advertising sync transfer command handler type. */ LHCI_MSG_CIS_MST, /*!< Connected isochronous stream master features command handler type. */ LHCI_MSG_CIS_SLV, /*!< Connected isochronous stream slave features command handler type. */ + LHCI_MSG_BIS_MST, /*!< Broadcast isochronous stream master features command handler type. */ + LHCI_MSG_BIS_SLV, /*!< Broadcast isochronous stream slave features command handler type. */ LHCI_MSG_ISO, /*!< Isochronous features command handler type. */ + LHCI_MSG_PC, /*!< Power control handler type. */ LHCI_MSG_VS_EXT, /*!< Extended vendor specific command handler type. */ LHCI_MSG_TESTER, /*!< Tester vendor specific command handler type. */ LHCI_MSG_TOTAL /*!< Total number of command handlers. */ @@ -287,6 +307,9 @@ typedef struct wsfQueue_t evtQ; /*!< Event queue. */ wsfQueue_t isoQ; /*!< ISO queue. */ bool_t evtTrPending; /*!< Event transport in progress. */ + + uint8_t supCmds[HCI_SUP_CMD_LEN]; + /*!< Supported HCI commands bit mask. */ } lhciPersistCb_t; /*! \brief Control block of the LL HCI subsystem (cleared with resets). */ @@ -295,6 +318,7 @@ typedef struct uint64_t evtMsk; /*!< General event mask. */ uint64_t evtMskPg2; /*!< General event mask page 2. */ uint64_t leEvtMsk; /*!< LE specific event mask. */ + lhciCompHandler_t evtCompCback; /*!< Event complete handler. */ uint8_t numScanReqRcvd; /*!< Number of scan request received. */ uint8_t hwErrorCode; /*!< Hardware error code. */ @@ -308,23 +332,24 @@ typedef struct uint32_t genPktCnt; /*!< Generate ACL packet count. */ uint32_t genOctetCnt; /*!< Generate ACL octet count. */ - bool_t recvIsoSink; /*!< Receive ISO sink. */ - uint32_t recvIsoPktCnt; /*!< Receive ISO packet count. */ - uint32_t recvIsoOctetCnt; /*!< Receive Iso octet count. */ - bool_t isoGenEnaFlag; /*!< Generate ISO enable flag. */ - uint8_t isoGenPldCnt; /*!< Generate ISO packet fill value. */ - uint16_t isoGenPktLen; /*!< Generate ISO packet length (0 to disable). */ - uint32_t isoGenPktCnt; /*!< Generate ISO packet count. */ - uint32_t isoGenOctetCnt; /*!< Generate ISO octet count. */ - - bool_t isoTxTest; /*!< TRUE if ISO Tx test is enabled. */ - bool_t isoRxTest; /*!< TRUE if ISO Rx test is enabled. */ - uint8_t isoTxTestPlLen; /*!< ISO Tx test payload length. */ - uint8_t isoRxTestPlLen; /*!< ISO Rx test payload length. */ - uint8_t numAdvReport; /*!< Number of pending advertising reports. */ } lhciCb_t; +/*! \brief Control block for ISO data generator. */ +typedef struct +{ + bool_t recvIsoSink; /*!< Receive ISO sink. */ + uint32_t recvIsoPktCnt; /*!< Receive ISO packet count. */ + uint32_t recvIsoOctetCnt; /*!< Receive ISO octet count. */ + bool_t genEnaFlag; /*!< Generate ISO enable flag. */ + uint8_t genPldCnt; /*!< Generate ISO packet fill value. */ + uint16_t genPktLen; /*!< Generate ISO packet length (0 to disable). */ + uint32_t genPktCnt; /*!< Generate ISO packet count. */ + uint32_t genOctetCnt; /*!< Generate ISO octet count. */ + + bool_t isoRxTest; /*!< TRUE if ISO Rx test is enabled. */ +} lhciIsoCb_t; + /************************************************************************************************** Global Variables **************************************************************************************************/ @@ -347,6 +372,9 @@ extern lhciPersistCb_t lhciPersistCb; /* Control block */ extern lhciCb_t lhciCb; +/* Control block for ISO data generation. */ +extern lhciIsoCb_t lhciIsoCb; + /* Handler duration watermark in microseconds. */ extern uint16_t lhciHandlerWatermarkUsec; @@ -361,7 +389,6 @@ void lhciReset(void); void lhciRecv(uint8_t type, uint8_t *pBuf); void lhciSendComplete(uint8_t type, uint8_t *pBuf); bool_t lhciService(uint8_t *pType, uint16_t *pLen, uint8_t **pBuf); -void lhciSendIsoComplete(uint8_t type, uint8_t *pBuf); void lhciSendHwError(uint8_t code); /* Handlers */ @@ -371,9 +398,9 @@ uint8_t *lhciRecvAcl(void); void lhciAclRecvPending(uint16_t handle, uint8_t numBufs); void lhciGenerateAcl(uint16_t handle, uint16_t pktLen, uint8_t numPkts); -void lhciIsoSendComplete(uint16_t handle, uint8_t numBufs); +void lhciIsoSendComplete(uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts); uint8_t *lhciRecvIso(void); -void lhciIsoRecvPending(uint16_t handle, uint8_t numBufs); +void lhciIsoRecvPending(uint8_t numHandles, uint16_t *pHandle, uint16_t *pNumPkts); void lhciGenerateIso(uint16_t handle, uint16_t pktLen, uint8_t numPkts); /* Command parser */ @@ -394,7 +421,10 @@ bool_t lhciPhyDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciPastDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciMstCisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciSlvCisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); +bool_t lhciSlvBisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); +bool_t lhciMstBisDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciIsoDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); +bool_t lhciPclDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciCommonVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); bool_t lhciConnVsStdDecodeCmdPkt(LhciHdr_t *pHdr, uint8_t *pBuf); @@ -424,7 +454,10 @@ bool_t lhciScEncodeEvtPkt(LlEvt_t *pEvt); bool_t lhciPhyEncodeEvtPkt(LlEvt_t *pEvt); bool_t lhciMstCisEncodeEvtPkt(LlEvt_t *pEvt); bool_t lhciSlvCisEncodeEvtPkt(LlEvt_t *pEvt); +bool_t lhciSlvBigEncodeEvtPkt(LlEvt_t *pEvt); +bool_t lhciMstBisEncodeEvtPkt(LlEvt_t *pEvt); bool_t lhciIsoEncodeEvtPkt(LlEvt_t *pEvt); +bool_t lhciPclEncodeEvtPkt(LlEvt_t *pEvt); bool_t lhciSlvVsStdEncodeEvtPkt(LlEvt_t *pEvt); @@ -433,6 +466,7 @@ bool_t lhciSlvVsStdEncodeEvtPkt(LlEvt_t *pEvt); uint8_t *lhciAllocEvt(uint8_t evtCode, uint8_t paramLen); uint8_t *lhciAllocCmdCmplEvt(uint8_t paramLen, uint16_t opCode); void lhciConnSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam, uint16_t handle); +void lhciPclSendCmdCmplEvt(LhciHdr_t *pCmdHdr, uint8_t status, uint8_t paramLen, uint8_t *pParam, uint16_t handle); /* Command packet. */ uint8_t lhciUnpackConnSpec(LlConnSpec_t *pConnSpec, const uint8_t *pBuf); @@ -543,8 +577,6 @@ static inline uint8_t lhciPackVsEvt(uint8_t *pBuf, uint16_t vsEvtCode) * \brief Send an event. * * \param pEvtBuf Buffer containing event. - * - * \return None. */ /*************************************************************************************************/ static inline void lhciSendEvt(uint8_t *pEvtBuf) @@ -557,8 +589,6 @@ static inline void lhciSendEvt(uint8_t *pEvtBuf) * \brief Send a command complete event. * * \param pEvtBuf Buffer containing command complete event. - * - * \return None. */ /*************************************************************************************************/ static inline void lhciSendCmdCmplEvt(uint8_t *pEvtBuf) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main.c index 5a1bf4f7624..aa223166705 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -83,8 +84,6 @@ static inline uint8_t lhciUnpackHdr(LhciHdr_t *pHdr, const uint8_t *pBuf) * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) @@ -93,7 +92,11 @@ void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) uint32_t startTime; uint32_t endTime; - startTimeValid = PalBbGetTimestamp(&startTime); + startTimeValid = PalBbGetTimestamp(NULL); + if (startTimeValid) + { + startTime = PalBbGetCurrentTime(); + } if (event & LHCI_EVT_ACL_RCVD) { @@ -149,6 +152,11 @@ void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) { lhciPersistCb.evtTrPending = FALSE; ChciTrNeedsService(CHCI_TR_PROT_BLE); + + if (lhciCb.evtCompCback) + { + lhciCb.evtCompCback(); + } } if (event & LHCI_EVT_HW_ERR) @@ -165,9 +173,10 @@ void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) } if (startTimeValid && - PalBbGetTimestamp(&endTime)) + PalBbGetTimestamp(NULL)) { - uint32_t durUsec = BB_TICKS_TO_US(endTime - startTime); + endTime = PalBbGetCurrentTime(); + uint32_t durUsec = BbGetTargetTimeDelta(endTime, startTime); if (lhciHandlerWatermarkUsec < durUsec) { lhciHandlerWatermarkUsec = durUsec; @@ -181,15 +190,18 @@ void LhciHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) * * \param type Type of message. * \param pBuf Pointer to received message. - * - * \return None. */ /*************************************************************************************************/ void lhciRecv(uint8_t type, uint8_t *pBuf) { switch (type) { - case CHCI_TR_TYPE_DATA: + case CHCI_TR_TYPE_ISO: + WsfMsgEnq(&lhciPersistCb.isoQ, 0, pBuf); + WsfSetEvent(lhciPersistCb.handlerId, LHCI_EVT_ISO_RCVD); + break; + + case CHCI_TR_TYPE_ACL: WsfMsgEnq(&lhciPersistCb.aclQ, 0, pBuf); WsfSetEvent(lhciPersistCb.handlerId, LHCI_EVT_ACL_RCVD); break; @@ -199,11 +211,6 @@ void lhciRecv(uint8_t type, uint8_t *pBuf) WsfSetEvent(lhciPersistCb.handlerId, LHCI_EVT_CMD_RCVD); break; - case CHCI_TR_TYPE_ISO: - WsfMsgEnq(&lhciPersistCb.isoQ, 0, pBuf); - WsfSetEvent(lhciPersistCb.handlerId, LHCI_EVT_ISO_RCVD); - break; - default: WsfMsgFree(pBuf); break; @@ -216,8 +223,6 @@ void lhciRecv(uint8_t type, uint8_t *pBuf) * * \param type Type of message. * \param pBuf Pointer to transmitted message. - * - * \return None. */ /*************************************************************************************************/ void lhciSendComplete(uint8_t type, uint8_t *pBuf) @@ -245,11 +250,19 @@ void lhciSendComplete(uint8_t type, uint8_t *pBuf) WsfMsgFree(pBuf); break; - case CHCI_TR_TYPE_DATA: + case CHCI_TR_TYPE_ACL: WsfMsgFree(pBuf); LlRecvAclDataComplete(1); break; +#if (BT_VER >= LL_VER_BT_CORE_SPEC_5_2) + /* TODO: Use function pointer to allow run time configuration of supported versions. */ + case CHCI_TR_TYPE_ISO: + WsfMsgFree(pBuf); + LlRecvIsoDataComplete(1); + break; +#endif + default: break; } @@ -294,14 +307,13 @@ bool_t lhciService(uint8_t *pType, uint16_t *pLen, uint8_t **pBuf) /* Additionally check if ISO data needs servicing. */ if ((pBufTemp = lhciServiceIso()) != NULL) { + BYTES_TO_UINT16(len, &pBufTemp[2]); + len += HCI_ISO_HDR_LEN; - len = pBufTemp[2] + HCI_ISO_HDR_LEN; lhciPersistCb.evtTrPending = TRUE; - *pType = CHCI_TR_TYPE_ISO; *pLen = len; *pBuf = pBufTemp; - return TRUE; } } @@ -315,7 +327,7 @@ bool_t lhciService(uint8_t *pType, uint16_t *pLen, uint8_t **pBuf) len += HCI_ACL_HDR_LEN; lhciPersistCb.evtTrPending = TRUE; - *pType = CHCI_TR_TYPE_DATA; + *pType = CHCI_TR_TYPE_ACL; *pLen = len; *pBuf = pBufTemp; return TRUE; @@ -332,8 +344,6 @@ bool_t lhciService(uint8_t *pType, uint16_t *pLen, uint8_t **pBuf) * \brief Signal transport hardware error. * * \param code Error code. - * - * \return None. */ /*************************************************************************************************/ void lhciSendHwError(uint8_t code) @@ -346,8 +356,6 @@ void lhciSendHwError(uint8_t code) /*! * \brief Reset HCI state. * - * \return None. - * * This function is called at the end of a HCI reset. */ /*************************************************************************************************/ @@ -364,12 +372,12 @@ void lhciReset(void) /*! * \brief Set default Hci supported cmds. * - * \return None. + * \param pBuf Buffer to set supported commands. * * This function is called at reset by lmgr. */ /*************************************************************************************************/ -void LhciSetDefaultHciSupCmd(uint8_t *pBuf) +static void LhciSetDefaultHciSupCmd(uint8_t *pBuf) { pBuf[5] = HCI_SUP_SET_EVENT_MASK | /* mandatory */ HCI_SUP_RESET; /* mandatory */ @@ -390,6 +398,8 @@ void LhciSetDefaultHciSupCmd(uint8_t *pBuf) HCI_SUP_LE_RECEIVER_TEST | /* Rx device */ HCI_SUP_LE_TRANSMITTER_TEST | /* Tx device */ HCI_SUP_LE_TEST_END; /* mandatory */ + pBuf[44] = HCI_SUP_LE_SET_HOST_FEATURE; /* v5.2 */ + pBuf[45] = HCI_SUP_LE_TRANSMITTER_TEST_V4; /* v5.2 */ pBuf[38] = HCI_SUP_LE_READ_TX_POWER; /* mandatory (5.0) */ if (lhciCmdTbl[LHCI_MSG_CONN]) @@ -531,24 +541,82 @@ void LhciSetDefaultHciSupCmd(uint8_t *pBuf) if (lhciCmdTbl[LHCI_MSG_CIS_MST]) { - pBuf[42] |= HCI_SUP_LE_READ_BUF_SIZE_V2 | /* Isochronous stream master */ - HCI_SUP_LE_SET_CIG_PARAM | /* Isochronous stream master */ - HCI_SUP_LE_CREATE_CIS | /* Isochronous stream master */ - HCI_SUP_LE_REMOVE_CIG; /* Isochronous stream master */ - - pBuf[44] |= HCI_SUP_LE_SETUP_ISO_DATA_PATH | /* Isochronous stream master */ - HCI_SUP_LE_REMOVE_ISO_DATA_PATH | /* Isochronous stream master */ - HCI_SUP_LE_REQ_PEER_SCA; /* Isochronous stream master */ + pBuf[41] |= HCI_SUP_LE_SET_CIG_PARAM; /* ISO CIS master */ + pBuf[42] |= HCI_SUP_LE_SET_CIG_PARAM_TEST | /* ISO CIS master */ + HCI_SUP_LE_CREATE_CIS | /* ISO CIS master */ + HCI_SUP_LE_REMOVE_CIG; /* ISO CIS master */ } if (lhciCmdTbl[LHCI_MSG_CIS_SLV]) { - pBuf[42] |= HCI_SUP_LE_READ_BUF_SIZE_V2 | /* Isochronous stream master */ - HCI_SUP_LE_ACCEPT_CIS_REQ | /* Isochronous stream master */ - HCI_SUP_LE_REJECT_CIS_REQ; /* Isochronous stream master */ + pBuf[42] |= HCI_SUP_LE_ACCEPT_CIS_REQ | /* ISO CIS slave */ + HCI_SUP_LE_REJECT_CIS_REQ; /* ISO CIS slave */ + } + + if (lhciCmdTbl[LHCI_MSG_BIS_MST]) + { + pBuf[43] |= HCI_SUP_LE_BIG_CREATE_SYNC | /* ISO BIS master */ + HCI_SUP_LE_BIG_TERMINATE_SYNC; /* ISO BIS master */ + } - pBuf[44] |= HCI_SUP_LE_SETUP_ISO_DATA_PATH | /* Isochronous stream master */ - HCI_SUP_LE_REMOVE_ISO_DATA_PATH | /* Isochronous stream master */ - HCI_SUP_LE_REQ_PEER_SCA; /* Isochronous stream master */ + if (lhciCmdTbl[LHCI_MSG_BIS_SLV]) + { + pBuf[42] |= HCI_SUP_LE_CREATE_BIG | /* ISO BIS slave */ + HCI_SUP_LE_CREATE_BIG_TEST | /* ISO BIS slave */ + HCI_SUP_LE_TERMINATE_BIG; /* ISO BIS slave */ } + + if (lhciCmdTbl[LHCI_MSG_ISO]) + { + pBuf[41] |= HCI_SUP_LE_READ_BUF_SIZE_V2 | /* ISO */ + HCI_SUP_LE_READ_ISO_TX_SYNC; /* ISO */ + pBuf[44] |= HCI_SUP_LE_SETUP_ISO_DATA_PATH | /* ISO */ + HCI_SUP_LE_REMOVE_ISO_DATA_PATH | /* ISO */ + HCI_SUP_LE_REQ_PEER_SCA; /* ISO */ + + pBuf[43] |= HCI_SUP_LE_ISO_TRANSMIT_TEST | /* ISO */ + HCI_SUP_LE_ISO_RECEIVE_TEST | /* ISO */ + HCI_SUP_LE_ISO_READ_TEST_COUNTERS; /* ISO */ + pBuf[44] |= HCI_SUP_LE_ISO_TEST_END | /* ISO */ + HCI_SUP_LE_READ_ISO_LINK_QUALITY; /* ISO */ + + pBuf[45] |= HCI_SUP_READ_LOCAL_SUP_CODECS_V2 | /* ISO */ + HCI_SUP_READ_LOCAL_SUP_CODEC_CAP | /* ISO */ + HCI_SUP_READ_LOCAL_SUP_CTR_DLY | /* ISO */ + HCI_SUP_CONFIG_DATA_PATH; /* ISO */ + } + + if (lhciCmdTbl[LHCI_MSG_PC]) + { + pBuf[44] |= HCI_SUP_LE_ENH_READ_TX_POWER_LEVEL | /* LEPC */ + HCI_SUP_LE_READ_REMOTE_TX_POWER_LEVEL | /* LEPC */ + HCI_SUP_LE_SET_PATH_LOSS_REPORT_PARAM | /* LEPC */ + HCI_SUP_LE_SET_PATH_LOSS_REPORT_PARAM | /* LEPC */ + HCI_SUP_LE_SET_PATH_LOSS_REPORT_ENABLE | /* LEPC */ + HCI_SUP_LE_SET_TX_POWER_REPORT_ENABLE; /* LEPC */ + } +} + +/*************************************************************************************************/ +/*! + * \brief Finalize HCI initialization. + * + * Called after all specific initializers. + */ +/*************************************************************************************************/ +void LhciInitFinalize(void) +{ + LhciSetDefaultHciSupCmd(lhciPersistCb.supCmds); +} + +/*************************************************************************************************/ +/*! + * \brief Register an event complete callback. + * + * \param compCback Event completion callback. + */ +/*************************************************************************************************/ +void LhciRegisterSendTrCompleteHandler(lhciCompHandler_t compCback) +{ + lhciCb.evtCompCback = compCback; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main_iso.c new file mode 100644 index 00000000000..a5e2bfec05d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lhci/lhci_main_iso.c @@ -0,0 +1,62 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) Host Controller Interface (HCI) initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lhci_int.h" +#include "chci_api.h" +#include "hci_defs.h" +#include "ll_api.h" +#include "bb_api.h" +#include "pal_bb.h" +#include "wsf_assert.h" +#include "wsf_msg.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief LL HCI message dispatch handler. + * + * \param event WSF event. + * \param pMsg WSF message. + */ +/*************************************************************************************************/ +void LhciIsoHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) +{ + if (event & LHCI_EVT_ISO_RCVD) + { + uint8_t *pIsoBuf; + wsfHandlerId_t handlerId; + + while ((pIsoBuf = WsfMsgDeq(&lhciPersistCb.isoQ, &handlerId)) != NULL) + { + LlSendIsoData(pIsoBuf); + } + } + + LhciHandler(event, pMsg); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init.c index 88d0504ff65..fd9479ae504 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) slave initialization implementation file. + * \file + * + * \brief Link layer (LL) slave initialization implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -46,8 +47,6 @@ static uint16_t llHandlerWatermarkUsec = 0; * * \param pCfg Pointer to runtime configuration parameters. * - * \return None. - * * This function returns default value for the LL subsystem's runtime configurations. */ /*************************************************************************************************/ @@ -57,7 +56,7 @@ void LlGetDefaultRunTimeCfg(LlRtCfg_t *pCfg) const LlRtCfg_t defCfg = { /* Device */ - .compId = LL_COMP_ID_ARM, + .compId = HCI_ID_PACKETCRAFT, .implRev = LL_VER_NUM >> 16, .btVer = LL_VER_BT_CORE_SPEC_4_2, /* Advertiser */ @@ -80,10 +79,13 @@ void LlGetDefaultRunTimeCfg(LlRtCfg_t *pCfg) /* ISO */ .numIsoTxBuf = 0, .numIsoRxBuf = 0, - .maxIsoBufLen = 0, + .maxIsoSduLen = 0, .maxIsoPduLen = 0, + .maxCig = 0, .maxCis = 0, /* Disable CIS. */ - .subEvtSpaceDelay = 0, + .cisSubEvtSpaceDelay= 0, + .maxBig = 0, + .maxBis = 0, /* DTM */ .dtmRxSyncMs = 10000, /* PHY */ @@ -102,8 +104,6 @@ void LlGetDefaultRunTimeCfg(LlRtCfg_t *pCfg) * * \param pCfg Pointer to runtime configuration parameters (data must be static). * - * \return None. - * * This function initializes the LL subsystem's runtime configuration. * * \note This routine must be called only once before any other initialization routines. @@ -133,8 +133,6 @@ void LlInitRunTimeCfg(const LlRtCfg_t *pCfg) * * \param handlerId WSF handler ID. * - * \return None. - * * This function initializes the LL subsystem. It is called once upon system initialization. * It must be called before any other function in the LL API is called. */ @@ -169,7 +167,7 @@ void LlHandlerInit(wsfHandlerId_t handlerId) LlTestInit(); - LL_TRACE_INFO1(" opModeFlags = 0x%08x", lmgrCb.opModeFlags); + LL_TRACE_INFO1(" opModeFlags = 0x%08x", lmgrCb.opModeFlags); } /*************************************************************************************************/ @@ -178,8 +176,6 @@ void LlHandlerInit(wsfHandlerId_t handlerId) * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) @@ -188,7 +184,11 @@ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) uint32_t startTime; uint32_t endTime; - startTimeValid = PalBbGetTimestamp(&startTime); + startTimeValid = PalBbGetTimestamp(NULL); + if (startTimeValid) + { + startTime = PalBbGetCurrentTime(); + } if (event != 0) { @@ -208,9 +208,10 @@ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) } if (startTimeValid && - PalBbGetTimestamp(&endTime)) + PalBbGetTimestamp(NULL)) { - uint32_t durUsec = BB_TICKS_TO_US(endTime - startTime); + endTime = PalBbGetCurrentTime(); + uint32_t durUsec = BbGetTargetTimeDelta(endTime, startTime); if (llHandlerWatermarkUsec < durUsec) { llHandlerWatermarkUsec = durUsec; @@ -223,8 +224,6 @@ void LlHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) /*! * \brief Reset LL subsystem. * - * \return None. - * * Reset the LL subsystem. All active connections are closed and all radio procedures such as * scanning or advertising are terminated. */ @@ -252,8 +251,6 @@ void LlReset(void) * * \param evtCback Client callback function. * - * \return None. - * * This function is called by a client to register for LL events. */ /*************************************************************************************************/ @@ -314,8 +311,8 @@ void LlGetConnContextSize(uint8_t *pMaxConn, uint16_t *pConnCtxSize) /*! * \brief Get extended scanner context size. * - * \param pMaxPerScan Buffer to return the maximum number of extended scanners. - * \param pPerScanCtxSize Buffer to return the size in bytes of the extended scanner context. + * \param pMaxExtScan Buffer to return the maximum number of extended scanners. + * \param pExtScanCtxSize Buffer to return the size in bytes of the extended scanner context. * * Return the advertising set context sizes. */ @@ -331,8 +328,8 @@ void LlGetExtScanContextSize(uint8_t *pMaxExtScan, uint16_t *pExtScanCtxSize) /*! * \brief Get extended initiator context size. * - * \param pMaxPerScan Buffer to return the maximum number of extended initiators. - * \param pPerScanCtxSize Buffer to return the size in bytes of the extended initiator context. + * \param pMaxExtInit Buffer to return the maximum number of extended initiators. + * \param pExtInitCtxSize Buffer to return the size in bytes of the extended initiator context. * * Return the advertising set context sizes. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master.c index f2d3d26d758..ea93c8ada9c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,8 +31,6 @@ /*! * \brief Initialize LL subsystem for operation as an scanning master. * - * \return None. - * * This function initializes the LL subsystem for use as an scanning master. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master_ae.c index 977eceb2190..2ede064632d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -53,8 +54,6 @@ uint16_t LlInitExtScanMem(uint8_t *pFreeMem, uint32_t freeMemSize) /*! * \brief Initialize LL subsystem for operation as an scanning master. * - * \return None. - * * This function initializes the LL subsystem for use as an scanning master. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave.c index 36ad002331b..cab593267ce 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,8 +31,6 @@ /*! * \brief Initialize LL subsystem for operation as an advertising slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising slave. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave_ae.c index bb575a63cae..9aa264f78b4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -59,8 +60,6 @@ uint16_t LlInitExtAdvMem(uint8_t *pFreeMem, uint32_t freeMemSize) /*! * \brief Initialize LL subsystem for operation for extended advertising slave. * - * \return None. - * * This function initializes the LL subsystem for use as an extended advertising slave. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_master.c new file mode 100644 index 00000000000..d88f5966018 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_master.c @@ -0,0 +1,42 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave initialization implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_api_bis_master.h" +#include "lmgr_api_iso.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for slave broadcast isochronous stream. + * + * This function initializes the LL subsystem for use as a slave broadcast isochronous stream. + */ +/*************************************************************************************************/ +void LlBisMasterInit(void) +{ + WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ + + LmgrIsoInit(); + LctrMstBisInit(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_slave.c new file mode 100644 index 00000000000..d92480e1795 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_bis_slave.c @@ -0,0 +1,71 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave initialization implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_api_bis_slave.h" +#include "lmgr_api_iso.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize memory for BIS. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + * + * This function allocates memory for BIS slave. + * + * \note This routine must be called after LlInitRunTimeCfg() but only once before any + * other initialization routines. + */ +/*************************************************************************************************/ +uint16_t LlInitBisMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + WSF_ASSERT(pLctrRtCfg); + WSF_ASSERT(pFreeMem); + + uint16_t bytesUsed = 0; + +#if (LL_MAX_BIG > 0) + bytesUsed = LctrInitBisMem(pFreeMem, freeMemSize); +#endif + + return bytesUsed; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for slave broadcast isochronous stream. + * + * This function initializes the LL subsystem for use as a slave broadcast isochronous stream. + */ +/*************************************************************************************************/ +void LlBisSlaveInit(void) +{ + WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ + + LmgrIsoInit(); + LctrSlvBisInit(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_master.c new file mode 100644 index 00000000000..293c02ada66 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_master.c @@ -0,0 +1,45 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) master initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lmgr_api_iso.h" +#include "ll_api.h" +#include "lmgr_api_cis_master.h" +#include "lctr_api_cis_master.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for master connected isochronous stream. + * + * This function initializes the LL subsystem for use as a master connected isochronous stream. + */ +/*************************************************************************************************/ +void LlCisMasterInit(void) +{ + WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ + + LmgrIsoInit(); + LmgrMstCisInit(); + LctrMstCisInit(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_slave.c new file mode 100644 index 00000000000..c7c8aac7aec --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_cis_slave.c @@ -0,0 +1,73 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave initialization implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_api.h" +#include "lctr_api_cis_slave.h" +#include "lctr_api_cis.h" +#include "lmgr_api_iso.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize memory for CIS. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + * + * This function allocates memory for CIS slave. + * + * \note This routine must be called after LlInitRunTimeCfg() but only once before any + * other initialization routines. + */ +/*************************************************************************************************/ +uint16_t LlInitCisMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + WSF_ASSERT(pLctrRtCfg); + WSF_ASSERT(pFreeMem); + + uint16_t bytesUsed = 0; + +#if (LL_MAX_CIS > 0) + bytesUsed = LctrInitCisMem(pFreeMem, freeMemSize); +#endif + + return bytesUsed; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for slave connected isochronous stream. + * + * This function initializes the LL subsystem for use as a slave connected isochronous stream. + */ +/*************************************************************************************************/ +void LlCisSlaveInit(void) +{ + WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ + + LmgrIsoInit(); + LctrCisSlvInit(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_cs2.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_cs2.c index 4c670825977..86d5df4b61c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_cs2.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_cs2.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) channel selection 2 initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) channel selection 2 initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -27,8 +28,6 @@ /*! * \brief Initialize LL subsystem for secure connections. * - * \return None. - * * This function initializes the LL subsystem for secure connections. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_master.c index 2cc3faf85d5..807845a1a4a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -31,8 +32,6 @@ /*! * \brief Initialize LL subsystem for operation as a connectable master. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and connectable master. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_slave.c index a6da257b91b..4138a4da43e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -60,8 +61,6 @@ uint16_t LlInitConnMem(uint8_t *pFreeMem, uint32_t freeMemSize) /*! * \brief Initialize LL subsystem for operation as a connectable slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and connectable slave. */ /*************************************************************************************************/ @@ -80,8 +79,6 @@ void LlConnSlaveInit(void) * \param sendCompCback Client ACL send complete callback function. * \param recvPendCback Client ACL receive pending callback function. * - * \return None. - * * This function is called by a client to register for ACL data. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_master.c index 6e6498a2925..6316bbac74f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) encryptable master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) encryptable master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -31,8 +32,6 @@ /*! * \brief Initialize LL subsystem for operation as a encryptable connectable master. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and encryptable * connectable master. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_slave.c index e02dc1b628b..2d70ac8a22c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) encryptable slave initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) encryptable slave initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -31,8 +32,6 @@ /*! * \brief Initialize LL subsystem for operation as a encryptable connectable slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising and encryptable * connectable slave. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master.c index f5f0e7db1d3..633251a2d99 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for operation as an initiating master. * - * \return None. - * * This function initializes the LL subsystem for use as an initiating master. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master_ae.c index e30a98883d6..1d01bcacf52 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_init_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for operation as an initiating master. * - * \return None. - * * This function initializes the LL subsystem for use as an initiating master. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_iso.c new file mode 100644 index 00000000000..2a8f3ddaa3c --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_iso.c @@ -0,0 +1,70 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave initialization implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ +#include "lctr_api_iso.h" +#include "lmgr_api.h" +#include "lctr_api.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Register ISO handler. + * + * \param sendIsoCompCback Client ISO send complete callback function. + * \param recvIsoPendCback Client ISO receive pending callback function. + * + * This function is called by a client to register for ACL data. + */ +/*************************************************************************************************/ +void LlIsoRegister(llIsoCback_t sendIsoCompCback, llIsoCback_t recvIsoPendCback) +{ + lmgrPersistCb.sendIsoCompCback = sendIsoCompCback; + lmgrPersistCb.recvIsoPendCback = recvIsoPendCback; +} + +/*************************************************************************************************/ +/*! + * \brief Initialize memory for ISO. + * + * \param pFreeMem Pointer to free memory. + * \param freeMemSize Size of pFreeMem. + * + * \return Amount of free memory consumed. + * + * This function allocates memory for CIS slave. + * + * \note This routine must be called after LlInitRunTimeCfg() but only once before any + * other initialization routines. + */ +/*************************************************************************************************/ +uint16_t LlInitIsoMem(uint8_t *pFreeMem, uint32_t freeMemSize) +{ + WSF_ASSERT(pLctrRtCfg); + WSF_ASSERT(pFreeMem); + + uint16_t bytesUsed = 0; + + bytesUsed = LctrInitIsoMem(pFreeMem, freeMemSize); + + return bytesUsed; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_master_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_master_phy.c index 76d08b27270..5d173d9e2d8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_master_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_master_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) PHY features initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) PHY features initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for PHY features (master). * - * \return None. - * * This function initializes the LL subsystem for master PHY features. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_past.c index 94a75312cbb..119554dfbaa 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for PAST(Periodic advertising sync transfer). * - * \return None. - * * This function initializes the LL subsystem for PAST(Periodic advertising sync transfer). */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_pc.c new file mode 100644 index 00000000000..2b31cc085b7 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_pc.c @@ -0,0 +1,39 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) power control initialization implementation file. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_api_pc.h" +#include "ll_api.h" +#include "lhci_api.h" +#include "wsf_assert.h" + +/*************************************************************************************************/ +/*! + * \brief Initialize LL subsystem for operation for power control. + * + * This function initializes the LL subsystem for power control. + */ +/*************************************************************************************************/ +void LlPowerControlInit(void) +{ + LhciPowerControlInit(); + LctrPowerControlInit(); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_priv.c index 5e61d3b6e29..aa55be5a072 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) privacy initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) privacy initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for operation as an advertising slave. * - * \return None. - * * This function initializes the LL subsystem for use as an advertising slave. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_sc.c index 115551f3c9a..ba881f75a68 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) secure connections initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) secure connections initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,8 +31,6 @@ /*! * \brief Initialize LL subsystem for secure connections. * - * \return None. - * * This function initializes the LL subsystem for secure connections. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_slave_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_slave_phy.c index 0532e929be9..0cbf0d2b61f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_slave_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_init_slave_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) PHY features initialization implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) PHY features initialization implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -29,8 +30,6 @@ /*! * \brief Initialize LL subsystem for PHY features (slave). * - * \return None. - * * This function initializes the LL subsystem for slave PHY features. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main.c index 9e1e2feb823..284369d9859 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) slave parameter interface implementation file. + * \file + * + * \brief Link layer (LL) slave parameter interface implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -50,8 +51,8 @@ /*! \brief Check if periodic adv is enabled (ae functionality). */ LctrIsPerAdvEnabledFn_t LctrPerAdvEnabled; /*!< Lctr Per Adv Enabled check function (defined if AE supported). */ -/*! \brief Check if periodic adv is enabled (ae functionality). */ -LctrIsPerAdvEnabledFn_t LctrPerAdvEnabled; /*!< Lctr Per Adv Enabled check function (defined if AE supported). */ +/*! \brief Update the channel map for CIS. */ +LctrUpdateCisChanMapFn_t LctrUpdateCisChanMapFn; /*!< Lctr Per Adv Enabled check function (defined if AE supported). */ /*! \brief Check is Ext Scan is enabled (ae functionality). */ LctrExtCheckFn_t LctrMstExtScanEnabled; @@ -65,8 +66,6 @@ LctrExtCheckFn_t LctrMstExtInitEnabled; * * \param pAddr Bluetooth device address. * - * \return None. - * * Set the BD address to be used by LL. */ /*************************************************************************************************/ @@ -86,8 +85,6 @@ void LlSetBdAddr(const uint8_t *pAddr) * * \param pAddr Bluetooth device address. * - * \return None. - * * Get the BD address currently used by LL or all zeros if address is not set. */ /*************************************************************************************************/ @@ -230,8 +227,6 @@ uint8_t LlGetRandAddr(uint8_t *pAddr) * \param pCompId Company ID. * \param pBtVer Bluetooth version. * \param pImplRev Implementation revision. - * - * \return None. */ /*************************************************************************************************/ void LlGetVersion(uint16_t *pCompId, uint8_t *pBtVer, uint16_t *pImplRev) @@ -249,8 +244,6 @@ void LlGetVersion(uint16_t *pCompId, uint8_t *pBtVer, uint16_t *pImplRev) * * \param pStates Supported states bitmask. * - * \return None. - * * Return the states supported by the LL. */ /*************************************************************************************************/ @@ -269,8 +262,6 @@ void LlGetSupStates(uint8_t *pStates) * * \param pFeatures Supported features bitmask. * - * \return None. - * * Return the LE features supported by the LL. */ /*************************************************************************************************/ @@ -352,6 +343,7 @@ uint8_t LlSetOpFlags(uint32_t flags, bool_t enable) LL_OP_MODE_FLAG_ENA_SLV_AUX_SCAN_RSP_ADI | LL_OP_MODE_FLAG_ENA_SLV_AUX_IND_ADVA | LL_OP_MODE_FLAG_ENA_ADV_CHAN_RAND | + LL_OP_MODE_DISABLE_POWER_MONITOR | LL_OP_MODE_FLAG_ENA_LLCP_TIMER | LL_OP_MODE_FLAG_IGNORE_CRC_ERR_TS; @@ -517,6 +509,38 @@ uint8_t LlRemoveDeviceFromWhitelist(uint8_t addrType, bdAddr_t pAddr) return LL_SUCCESS; } +/*************************************************************************************************/ +/*! + * \brief Set host feature. + * + * \param bitNum Bit position in the FeatureSet. + * \param bitVal Enable or disable feature. + * + * \return Status error code. + * + * Set or clear a bit in the feature controlled by the Host in the Link Layer FeatureSet + * stored in the Controller. + */ +/*************************************************************************************************/ +uint8_t LlSetHostFeatures(uint8_t bitNum, bool_t bitVal) +{ + LL_TRACE_INFO2("### LlApi ### LlSetHostFeatures, Bit=%d Value=%d", bitNum, bitVal); + + if ((LL_HOST_CONTROLLED_FEAT & (UINT64_C(1) << bitNum)) == 0) + { + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + if (lmgrCb.numConnEnabled) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + lmgrCb.features = (lmgrCb.features & ~(UINT64_C(1) << bitNum)) | (((uint64_t) bitVal) << bitNum); + + return LL_SUCCESS; +} + /*************************************************************************************************/ /*! * \brief Get random number. @@ -547,8 +571,6 @@ uint8_t LlGetRandNum(uint8_t *pRandNum) * \param pMinTxPwr Return buffer for minimum transmit power. * \param pMaxTxPwr Return buffer for maximum transmit power. * - * \return None. - * * Read the minimum and maximum transmit powers supported by the LL. */ /*************************************************************************************************/ @@ -566,8 +588,6 @@ void LlReadSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr) * \param pTxPathComp Return buffer for RF transmit path compensation value. * \param pRxPathComp Return buffer for RF receive path compensation value. * - * \return None. - * * Read the RF Path Compensation Values parameter used in the Tx Power Level and RSSI calculation. */ /*************************************************************************************************/ @@ -617,9 +637,7 @@ uint8_t LlWriteRfPathComp(int16_t txPathComp, int16_t rxPathComp) /*************************************************************************************************/ uint8_t LlSetChannelClass(const uint8_t *pChanMap) { - lctrChanMapUpdate_t *pMsg; uint64_t chanMap; - uint16_t handle; LL_TRACE_INFO0("### LlApi ### LlSetChannelClass"); @@ -632,70 +650,5 @@ uint8_t LlSetChannelClass(const uint8_t *pChanMap) return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - lmgrCb.chanClass = chanMap; - - /* Update for connections */ - for (handle = 0; handle < pLctrRtCfg->maxConn; handle++) - { - if ((LctrIsConnHandleEnabled(handle)) && - (LctrGetRole(handle) == LL_ROLE_MASTER)) - { - if (LctrIsProcActPended(handle, LCTR_CONN_MSG_API_CHAN_MAP_UPDATE) == TRUE) - { - return LL_ERROR_CODE_CMD_DISALLOWED; - } - - if ((pMsg = (lctrChanMapUpdate_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) - { - pMsg->hdr.handle = handle; - pMsg->hdr.dispId = LCTR_DISP_CONN; - pMsg->hdr.event = LCTR_CONN_MSG_API_CHAN_MAP_UPDATE; - - pMsg->chanMap = chanMap; - - WsfMsgSend(lmgrPersistCb.handlerId, pMsg); - } - } - } - - /* If periodic advertising is not included, return here. */ - if (LctrPerAdvEnabled) - { - /* Update for periodic adv sets */ - for(uint8_t perAdvHandle = 0; perAdvHandle < pLctrRtCfg->maxAdvSets; perAdvHandle++) - { - if (LctrPerAdvEnabled(perAdvHandle) == TRUE) - { - if ((pMsg = (lctrChanMapUpdate_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) - { - pMsg->hdr.handle = (uint16_t) perAdvHandle; - pMsg->hdr.dispId = LCTR_DISP_ACAD; - pMsg->hdr.event = LCTR_ACAD_MSG_CHAN_UPDATE; - pMsg->chanMap = chanMap; - - WsfMsgSend(lmgrPersistCb.handlerId, pMsg); - } - } - } - } - - return LL_SUCCESS; -} - -/*************************************************************************************************/ -/*! - * \brief Set Hci supported command - * - * \param byte Byte location of command - * \param bit Bit location of command - * \param enable Enable or disable command - * - * \return Status error code - * - */ -/*************************************************************************************************/ -uint8_t LlSetHciSupCmd(uint8_t byte, uint8_t bit, bool_t enable) -{ - lmgrCb.hciSupCommands[byte] = ((lmgrCb.hciSupCommands[byte] & ~(1 << bit)) | ((uint8_t) enable << bit)); - return LL_SUCCESS; + return LctrSetChannelClass(chanMap); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master.c index fa64d7114b5..2469c29e85d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master parameter interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master parameter interface implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -130,8 +131,6 @@ uint8_t LlSetScanParam(const LlScanParam_t *pParam) * \param enable Set to TRUE to enable scanning, FALSE to disable scanning. * \param filterDup Set to TRUE to filter duplicates. * - * \return None. - * * Enable or disable scanning. This function is only used when operating in master role. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master_ae.c index d600883cce5..8d0aa0eed59 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master control interface implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -159,8 +160,6 @@ uint8_t LlSetExtScanParam(uint8_t ownAddrType, uint8_t scanFiltPolicy, uint8_t s * \param duration Duration. * \param period Period. * - * \return None. - * * Enable or disable extended scanning. */ /*************************************************************************************************/ @@ -190,23 +189,31 @@ void LlExtScanEnable(uint8_t enable, uint8_t filterDup, uint16_t duration, uint1 } if ((LL_API_PARAM_CHECK == 1) && - ((enable != 0) && - ((filterDup > filterDupMax) || - ((perMs > 0) && (durMs == 0)) || /* Minimum Duration is 1. */ - ((perMs > 0) && (perMs <= durMs))))) /* Ensure Period > Duration. */ + (enable == TRUE)) { - lmgrCb.extScanEnaDelayCnt = 1; - LmgrSendExtScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); - return; - } + if (filterDup > filterDupMax) + { + lmgrCb.extScanEnaDelayCnt = 1; + LmgrSendExtScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); + return; + } - if ((LL_API_PARAM_CHECK == 1) && - ((enable != 0) && - ((filterDup == LL_SCAN_FILTER_DUP_ENABLE_PERIODIC) && ((duration == 0) || (period == 0))))) - { - lmgrCb.extScanEnaDelayCnt = 1; - LmgrSendExtScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); - return; + if ((filterDup == LL_SCAN_FILTER_DUP_ENABLE_PERIODIC) && + ((perMs == 0) || (durMs == 0))) + { + lmgrCb.extScanEnaDelayCnt = 1; + LmgrSendExtScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); + return; + } + + /* Ensure period > duration. */ + if (((perMs != 0) && (durMs != 0)) && + (durMs >= perMs)) + { + lmgrCb.extScanEnaDelayCnt = 1; + LmgrSendExtScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); + return; + } } if ((LL_API_PARAM_CHECK == 1) && @@ -277,12 +284,6 @@ uint8_t LlPeriodicAdvCreateSync(const LlPerAdvCreateSyncCmd_t *pParam) return LL_ERROR_CODE_MEM_CAP_EXCEEDED; } - /* If reporting is initially disabled and controller does not support LE_Set_Per_Adv_Rcv_En cmd, return error. */ - if (((pParam->options >> 1) & 0x01) && !(lmgrCb.hciSupCommands[40] & HCI_SUP_LE_SET_PER_ADV_RCV_ENABLE)) - { - return LL_ERROR_CODE_CONN_FAILED_TO_ESTABLISH; - } - lctrPerCreateSyncMsg_t *pMsg; if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) @@ -359,6 +360,7 @@ uint8_t LlPeriodicAdvTerminateSync(uint16_t syncHandle) LL_TRACE_WARN0("Legacy Advertising/Scanning operation enabled; extended commands not available"); return LL_ERROR_CODE_CMD_DISALLOWED; } + if ((LL_API_PARAM_CHECK == 1) && syncHandle > LL_SYNC_MAX_HANDLE) { @@ -426,6 +428,12 @@ uint8_t LlAddDeviceToPeriodicAdvList(const LlDevicePerAdvList_t *pParam) } uint64_t addr = BstreamToBda64(pParam->pAdvAddr); + + if (BbBlePeriodicListCheckAddr(pParam->advAddrType, addr, pParam->advSID)) + { + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + if (!BbBlePeriodicListAdd(pParam->advAddrType, addr, pParam->advSID)) { return LL_ERROR_CODE_MEM_CAP_EXCEEDED; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave.c index b9e0dbe25c3..f00155c5203 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave parameter interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave parameter interface implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -42,8 +43,6 @@ * * \param advTxPwr Advertising transmit power level. * - * \return None. - * * Set the advertising transmit power. */ /*************************************************************************************************/ @@ -151,8 +150,8 @@ uint8_t LlSetAdvParam(uint16_t advIntervalMin, uint16_t advIntervalMax, uint8_t pMsg->hdr.dispId = LCTR_DISP_ADV; pMsg->hdr.event = LCTR_ADV_MSG_PARAM_UPD; - pMsg->param.advInterMin = BB_BLE_TO_BB_TICKS(advIntervalMin); - pMsg->param.advInterMax = BB_BLE_TO_BB_TICKS(advIntervalMax); + pMsg->param.advInterMinUsec = BB_BLE_TO_US(advIntervalMin); + pMsg->param.advInterMaxUsec = BB_BLE_TO_US(advIntervalMax); pMsg->param.advType = advType; pMsg->param.ownAddrType = ownAddrType; pMsg->param.peerAddrType = peerAddrType; @@ -251,8 +250,6 @@ uint8_t LlSetScanRespData(uint8_t len, const uint8_t *pData) * * \param enable Set to TRUE to enable advertising, FALSE to disable advertising. * - * \return None. - * * Enable or disable advertising. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave_ae.c index 4b238a4d6f6..b644cad7442 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) master control interface implementation file. + * \file + * + * \brief Link layer (LL) master control interface implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -61,12 +62,12 @@ uint8_t LlSetAdvSetRandAddr(uint8_t handle, const uint8_t *pAddr) return LctrSetExtAdvSetRandAddr(handle, pAddr); } - /*************************************************************************************************/ /*! * \brief Read periodic channel map for slave or master * - * \param pBuf Packed packet buffer. + * \param handle handle. + * \param isAdv Handle is an advertiser. * * \return Channel map, packed into a 64bit int * @@ -125,7 +126,7 @@ uint8_t LlSetExtAdvParam(uint8_t handle, LlExtAdvParam_t *pExtAdvParam) LL_ADV_EVT_PROP_CONN_ADV_BIT; /* Maximum extended advertising interval is half the maximum BB clock rollover time. */ - const uint32_t bbDurMaxUsec = BB_TICKS_TO_US(UINT64_C(1) << 31); + const uint32_t bbDurMaxUsec = (BbGetBbTimerBoundaryUs() >> 1) + 1; const uint32_t validAdvInterMax = WSF_MIN(LL_MATH_DIV_625(bbDurMaxUsec), 0xFFFFFF); LL_TRACE_INFO2("### LlApi ### LlSetExtAdvParam, handle=%u, advEventProp=0x%04x", handle, pExtAdvParam->advEventProp); @@ -195,8 +196,6 @@ uint8_t LlSetExtAdvParam(uint8_t handle, LlExtAdvParam_t *pExtAdvParam) LL_TRACE_WARN1("Unsupported PHY, handle=%u", handle); return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; } - pExtAdvParam->priAdvInterMin = BB_BLE_TO_BB_TICKS(pExtAdvParam->priAdvInterMin); - pExtAdvParam->priAdvInterMax = BB_BLE_TO_BB_TICKS(pExtAdvParam->priAdvInterMax); return LctrSetExtAdvParam(handle, pExtAdvParam); } @@ -289,8 +288,6 @@ uint8_t LlSetExtScanRespData(uint8_t handle, uint8_t op, uint8_t fragPref, uint8 * \param numAdvSets Number of elements in enaParam[]. * \param enaParam Enable parameter table. * - * \return None. - * * Enable or disable extended advertising. */ /*************************************************************************************************/ @@ -298,8 +295,11 @@ void LlExtAdvEnable(uint8_t enable, uint8_t numAdvSets, LlExtAdvEnableParam_t en { LL_TRACE_INFO2("### LlApi ### LlExtAdvEnable: enable=%u, numAdvSets=%u", enable, numAdvSets); - /* Non-overlapping enable requests. */ - WSF_ASSERT(lmgrCb.extAdvEnaDelayCnt == 0); + if (lmgrCb.extAdvEnaDelayCnt != 0) + { + LL_TRACE_WARN0("Overlapped enable request"); + LmgrSendExtAdvEnableCnf(0, LL_ERROR_CODE_CMD_DISALLOWED); + } lmgrCb.advSetEnaStatus = LL_SUCCESS; @@ -574,15 +574,13 @@ uint8_t LlSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const uint /*! * \brief Set periodic advertising enable. * - * \param enable Set to TRUE to enable advertising, FALSE to disable advertising. * \param handle Advertising handle. - * - * \return None. + * \param enable Set to TRUE to enable advertising, FALSE to disable advertising. * * Enable or disable periodic advertising. */ /*************************************************************************************************/ -void LlSetPeriodicAdvEnable(uint8_t handle, uint8_t enable) +void LlSetPeriodicAdvEnable(uint8_t enable, uint8_t handle) { LL_TRACE_INFO2("### LlApi ### LlSetPeriodicAdvEnable: enable=%u, handle=%u", enable, handle); @@ -692,8 +690,6 @@ uint8_t LlSetExtAdvTxPhyOptions(uint8_t handle, uint8_t priPhyOpts, uint8_t secP * * \param phyOptions PHY options. * - * \return None. - * * Set the default TX PHY options for extended adv slave primary and secondary channel. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_master.c new file mode 100644 index 00000000000..54883773068 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_master.c @@ -0,0 +1,128 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) master control interface implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_api_bis_master.h" +#include "wsf_math.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include + +/************************************************************************************************** + Internal functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Check if the create BIG parameters are valid or not. + * + * \param pParam Create BIG test parameters. + * + * \return True if parameter is valid, False otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsBigCreateSyncParamsValid(LlBigCreateSync_t *pParam) +{ + const uint8_t MAX_BIG_HANDLE = 0xEF; + const uint16_t MAX_SYNC_HANDLE = 0x0EFF; + const uint8_t MAX_ENCRYPTION = 0x01; + const uint8_t MAX_MSE = 0x1F; + const uint16_t MIN_BIG_SYNC_TIMEOUT = 0x000A; + const uint16_t MAX_BIG_SYNC_TIMEOUT = 0x4000; + const uint8_t MIN_BIS = LL_MIN_BIS; + const uint8_t MAX_BIS = 0x1F; + + if (pParam->bigHandle > MAX_BIG_HANDLE) + { + LL_TRACE_WARN1("bigHandle=%u out of range", pParam->bigHandle); + return FALSE; + } + if (pParam->syncHandle > MAX_SYNC_HANDLE) + { + LL_TRACE_WARN1("syncHandle=%u out of range", pParam->syncHandle); + return FALSE; + } + if (pParam->encrypt > MAX_ENCRYPTION) + { + LL_TRACE_WARN1("encrypt=%u out of range", pParam->encrypt); + return FALSE; + } + if (pParam->mse > MAX_MSE) + { + LL_TRACE_WARN1("mse=%u out of range", pParam->mse); + return FALSE; + } + if ((pParam->bigSyncTimeout < MIN_BIG_SYNC_TIMEOUT) || (pParam->bigSyncTimeout > MAX_BIG_SYNC_TIMEOUT)) + { + LL_TRACE_WARN1("bigSyncTimeout=%u out of range", pParam->bigSyncTimeout); + return FALSE; + } + if ((pParam->numBis < MIN_BIS) || (pParam->numBis > MAX_BIS)) + { + LL_TRACE_WARN1("numBis=%u out of range", pParam->numBis); + return FALSE; + } + + return TRUE; +} + +/************************************************************************************************** + External functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Used to synchronize and receive PDUs from one or more BISes within a BIG. + * + * \param pCreateSync BIG Create Sync parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlBigCreateSync(LlBigCreateSync_t *pCreateSync) +{ + LL_TRACE_INFO2("### LlApi ### LlBigCreateSync bigHandle=%u syncHandle=%u", pCreateSync->bigHandle, pCreateSync->syncHandle); + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsBigCreateSyncParamsValid(pCreateSync) == FALSE)) + { + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + + return LctrMstBigCreateSync(pCreateSync); +} + +/*************************************************************************************************/ +/*! + * \brief Used to stop synchronization with the BIG or to cancel the process of synchronizing + * to BISes invoked by the HCI_LE_BIG_Create_Sync command + * + * \param bigHandle Used to identify the BIG. + */ +/*************************************************************************************************/ +void LlBigTerminateSync(uint8_t bigHandle) +{ + LL_TRACE_INFO1("### LlApi ### LlBigTerminateSync bigHandle=%u", bigHandle); + + LctrMstBigTerminateSync(bigHandle); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_slave.c new file mode 100644 index 00000000000..c52252815e5 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_bis_slave.c @@ -0,0 +1,355 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave control interface implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lctr_api_bis_slave.h" +#include "lctr_api_adv_slave_ae.h" +#include "wsf_trace.h" +#include + +/************************************************************************************************** + Internal functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Check if the create BIG parameters are valid or not. + * + * \param pParam Create BIG command parameters. + * + * \return TRUE if parameter is valid, FALSE otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsBigParamsValid(LlCreateBig_t *pParam) +{ + const uint8_t MAX_BIG_HANDLE = 0xEF; + const uint8_t MAX_ADV_HANDLE = 0xEF; + const uint8_t MIN_NUM_BIS = 0x01; + const uint8_t MAX_NUM_BIS = 0x1F; + const uint32_t MIN_SDU_INTERVAL = 0x00100; + const uint32_t MAX_SDU_INTERVAL = 0xFFFFF; + const uint16_t MAX_SDU = 0x0FFF; + const uint16_t MAX_TRANSPORT_LATENCY = 0x0FA0; + const uint8_t MAX_RTN = 0x0F; + const uint8_t MIN_PHY = 0x01; + const uint8_t MAX_PACKING = 0x01; + const uint8_t MAX_FRAMING = 0x01; + const uint8_t MAX_ENCRYPTION = 0x01; + + if (pParam->bigHandle > MAX_BIG_HANDLE) + { + LL_TRACE_WARN1("bigHandle=%u out of range", pParam->bigHandle); + return FALSE; + } + if (pParam->advHandle > MAX_ADV_HANDLE) + { + LL_TRACE_WARN1("advHandle=%u out of range", pParam->advHandle); + return FALSE; + } + if ((pParam->numBis < MIN_NUM_BIS) || (pParam->numBis > MAX_NUM_BIS)) + { + LL_TRACE_WARN1("numBis=%u out of range", pParam->numBis); + return FALSE; + } + if ((pParam->sduInterUsec < MIN_SDU_INTERVAL) || (pParam->sduInterUsec > MAX_SDU_INTERVAL)) + { + LL_TRACE_WARN1("sduIntervUsec=%u out of range", pParam->sduInterUsec); + return FALSE; + } + if (pParam->maxSdu > MAX_SDU) + { + LL_TRACE_WARN1("maxSdu=%u value out of range", pParam->maxSdu); + return FALSE; + } + if (pParam->mtlMs > MAX_TRANSPORT_LATENCY) + { + LL_TRACE_WARN1("mtl=%u value out of range", pParam->mtlMs); + return FALSE; + } + if (pParam->rtn > MAX_RTN) + { + LL_TRACE_WARN1("rtn=%u value out of range", pParam->rtn); + return FALSE; + } + if (pParam->phys < MIN_PHY) + { + LL_TRACE_WARN1("phy=0x%02x value out of range", pParam->phys); + return FALSE; + } + if (pParam->packing > MAX_PACKING) + { + LL_TRACE_WARN1("packing=%u value out of range", pParam->packing); + return FALSE; + } + if (pParam->framing > MAX_FRAMING) + { + LL_TRACE_WARN1("framing=%u value out of range", pParam->framing); + return FALSE; + } + if (pParam->encrypt > MAX_ENCRYPTION) + { + LL_TRACE_WARN1("encryption=%u value out of range", pParam->encrypt); + return FALSE; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the create BIG test parameters are valid or not. + * + * \param pParam Create BIG test parameters. + * + * \return True if parameter is valid, False otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsBigTestParamsValid(LlCreateBigTest_t *pParam) +{ + const uint8_t MAX_BIG_HANDLE = 0xEF; + const uint8_t MAX_ADV_HANDLE = 0xEF; + const uint8_t MIN_NUM_BIS = 0x01; + const uint8_t MAX_NUM_BIS = 0x1F; + const uint32_t MIN_SDU_INTERVAL = 0x00100; + const uint32_t MAX_SDU_INTERVAL = 0xFFFFF; + const uint16_t MIN_ISO_INTERVAL = 0x0004; + const uint16_t MAX_ISO_INTERVAL = 0x0C80; + const uint8_t MIN_NUM_NSE = 0x01; + const uint8_t MAX_NUM_NSE = 0x1F; + const uint16_t MAX_SDU = 0x0FFF; + const uint8_t MIN_PDU = 0x01; + const uint8_t MAX_PDU = 0xFB; + const uint8_t MIN_PHY = 0x01; + const uint8_t MAX_PACKING = 0x01; + const uint8_t MAX_FRAMING = 0x01; + const uint8_t MIN_BN = 0x01; + const uint8_t MAX_BN = 0x07; + const uint8_t MIN_IRC = 0x01; + const uint8_t MAX_IRC = 0x0F; + const uint8_t MAX_PTO = 0x0F; + const uint8_t MAX_ENCRYPTION = 0x01; + + if (pParam->bigHandle > MAX_BIG_HANDLE) + { + LL_TRACE_WARN1("bigHandle=%u out of range", pParam->bigHandle); + return FALSE; + } + if (pParam->advHandle > MAX_ADV_HANDLE) + { + LL_TRACE_WARN1("advHandle=%u out of range", pParam->advHandle); + return FALSE; + } + if ((pParam->numBis < MIN_NUM_BIS) || (pParam->numBis > MAX_NUM_BIS)) + { + LL_TRACE_WARN1("numBis=%u out of range", pParam->numBis); + return FALSE; + } + if ((pParam->sduInterUsec < MIN_SDU_INTERVAL) || (pParam->sduInterUsec > MAX_SDU_INTERVAL)) + { + LL_TRACE_WARN1("sduInterval=%u out of range", pParam->sduInterUsec); + return FALSE; + } + if ((pParam->isoInter < MIN_ISO_INTERVAL) || (pParam->isoInter > MAX_ISO_INTERVAL)) + { + LL_TRACE_WARN1("isoInterval=%u out of range", pParam->isoInter); + return FALSE; + } + if ((pParam->nse < MIN_NUM_NSE) || (pParam->nse > MAX_NUM_NSE)) + { + LL_TRACE_WARN1("NSE=%u out of range", pParam->nse); + return FALSE; + } + if (pParam->maxSdu > MAX_SDU) + { + LL_TRACE_WARN1("maxSdu=%u out of range", pParam->maxSdu); + return FALSE; + } + if ((pParam->maxPdu < MIN_PDU) || (pParam->maxPdu > MAX_PDU)) + { + LL_TRACE_WARN1("maxPdu=%u out of range", pParam->maxPdu); + return FALSE; + } + if (pParam->phys < MIN_PHY) + { + LL_TRACE_WARN1("phy=0x%02x out of range", pParam->phys); + return FALSE; + } + if (pParam->packing > MAX_PACKING) + { + LL_TRACE_WARN1("packing=%u out of range", pParam->packing); + return FALSE; + } + if (pParam->framing > MAX_FRAMING) + { + LL_TRACE_WARN1("framing=%u out of range", pParam->framing); + return FALSE; + } + if ((pParam->bn < MIN_BN) || (pParam->bn > MAX_BN)) + { + LL_TRACE_WARN1("BN=%u out of range", pParam->bn); + return FALSE; + } + if ((pParam->irc < MIN_IRC) || (pParam->irc > MAX_IRC)) + { + LL_TRACE_WARN1("IRC=%u out of range", pParam->irc); + return FALSE; + } + if (pParam->pto > MAX_PTO) + { + LL_TRACE_WARN1("PTO=%u out of range", pParam->pto); + return FALSE; + } + if (pParam->encrypt > MAX_ENCRYPTION) + { + LL_TRACE_WARN1("encrypt=%u out of range", pParam->encrypt); + return FALSE; + } + + if ((pParam->framing == LL_ISO_PDU_TYPE_UNFRAMED) && + (((pParam->isoInter * 1250) % pParam->sduInterUsec) > 0)) + { + LL_TRACE_WARN0("Unframed PDUs must have ISO_Interval that are multiples of the SDU_Interval"); + return FALSE; + } + + return TRUE; +} + +/************************************************************************************************** + External functions +**************************************************************************************************/ + +/*************************************************************************************************/ +/*! + * \brief Used by a broadcaster host to command is used to create one or more BISes of a BIG + * in the controller. + * + * \param pCreateBig Create BIG parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlCreateBig(LlCreateBig_t *pCreateBig) +{ + LL_TRACE_INFO2("### LlApi ### LlCreateBig bigHandle=%u advHandle=%u", pCreateBig->bigHandle, pCreateBig->advHandle); + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsBigParamsValid(pCreateBig) == FALSE)) + { + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + + if ((LL_API_PARAM_CHECK == 1) && + (LctrIsPerAdvEnabled(pCreateBig->advHandle) == FALSE)) + { + LL_TRACE_WARN1("Periodic advertiser not found, advHandle=%u", pCreateBig->advHandle); + return LL_ERROR_CODE_UNKNOWN_ADV_ID; + } + + uint8_t supPhyMask = LL_PHYS_LE_1M_BIT | + (pLctrRtCfg->phy2mSup ? LL_PHYS_LE_2M_BIT : 0) | + (pLctrRtCfg->phyCodedSup ? LL_PHYS_LE_CODED_BIT : 0); + + if ((LL_API_PARAM_CHECK == 1) && + (pCreateBig->phys & (~supPhyMask))) + { + LL_TRACE_WARN1("Unknown PHY bits, phys=%u", pCreateBig->phys); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + return LctrSlvBisCreateBig(pCreateBig); +} + +/*************************************************************************************************/ +/*! + * \brief Used by a broadcaster host to command is used to create one or more BISes of a BIG + * in the ISO test mode. + * + * \param pCreateBigTest Create BIG parameters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlCreateBigTest(LlCreateBigTest_t *pCreateBigTest) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO2("### LlApi ### LlCreateBigTest bigHandle=%u advHandle=%u", pCreateBigTest->bigHandle, pCreateBigTest->advHandle); + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsBigTestParamsValid(pCreateBigTest) == FALSE)) + { + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + + if ((LL_API_PARAM_CHECK == 1) && + (pCreateBigTest->nse < (pCreateBigTest->irc * pCreateBigTest->bn))) + { + LL_TRACE_WARN0("NSE not less than 'IRC * BN'"); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + if ((LL_API_PARAM_CHECK == 1) && + (LctrIsPerAdvEnabled(pCreateBigTest->advHandle) == FALSE)) + { + LL_TRACE_WARN1("Periodic advertiser not found, advHandle=%u", pCreateBigTest->advHandle); + return LL_ERROR_CODE_UNKNOWN_ADV_ID; + } + + uint8_t supPhyMask = LL_PHYS_LE_1M_BIT | + (pLctrRtCfg->phy2mSup ? LL_PHYS_LE_2M_BIT : 0) | + (pLctrRtCfg->phyCodedSup ? LL_PHYS_LE_CODED_BIT : 0); + + if ((LL_API_PARAM_CHECK == 1) && + (pCreateBigTest->phys & (~supPhyMask))) + { + LL_TRACE_WARN1("Unknown PHY bits, phys=%u", pCreateBigTest->phys); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + status = LctrSlvBisCreateBigTest(pCreateBigTest); + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used to terminate the transmission of all BISes of a BIG, or to cancel the process + * of creating a BIG using the HCI_LE_Create_BIG command from the Isochronous Broadcaster. + * + * \param bigHandle Used to identify the BIG. + * \param reason Termination reason. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlTerminateBig(uint8_t bigHandle, uint8_t reason) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO2("### LlApi ### LlTerminateBig bigHandle=%u advHandle=%u", bigHandle, reason); + + status = LctrSlvBisTerminateBig(bigHandle, reason); + + return status; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_master.c new file mode 100644 index 00000000000..ee19329f821 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_master.c @@ -0,0 +1,500 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) master control interface implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_api.h" +#if (LL_ENABLE_TESTER) +#include "ll_tester_api.h" +#endif +#include "lmgr_api.h" +#include "lmgr_api_cis_master.h" +#include "lctr_api_cis_master.h" +#include "lctr_api_conn.h" +#include "util/bstream.h" +#include "wsf_assert.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Check if the CIG parameters are valid or not. + * + * \param pCigParam Set CIG parameters. + * + * \return True if parameter is valid, False otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsCigParamsValid(LlCisCigParams_t *pCigParam) +{ + const uint8_t MAX_CIG_ID = 0xEF; + const uint32_t MIN_SDU_INTERVAL = 0x000FF; + const uint32_t MAX_SDU_INTERVAL = 0xFFFFF; + const uint8_t MAX_SCA = 0x07; + const uint8_t MAX_PACKING = 0x01; + const uint8_t MAX_FRAMING = 0x01; + const uint16_t MIN_TRANS_LATENCY = 0x0005; + const uint16_t MAX_TRANS_LATENCY = 0x0FA0; + const uint8_t MIN_NUM_CIS = 0x01; + const uint8_t MAX_NUM_CIS = 0x10; + const uint8_t MAX_CIS_ID = 0xEF; + const uint16_t MAX_SDU_SIZE = 0x0FFF; + const uint8_t MIN_PHY = 0x01; + const uint8_t MAX_PHY = 0x07; + const uint8_t MAX_RTE = 0x0F; + + if (pCigParam->cigId > MAX_CIG_ID) + { + return FALSE; + } + if (pCigParam->sduIntervalMToS != pCigParam->sduIntervalSToM) + { + /* For now, sduIntervalMToS shall be equal to the sduIntervalMToS */ + LL_TRACE_INFO0("LlIsCigParamsValid sduIntervalMToS != sduIntervalSToM"); + return FALSE; + } + if ((pCigParam->sduIntervalMToS < MIN_SDU_INTERVAL) || (pCigParam->sduIntervalMToS > MAX_SDU_INTERVAL)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid sduIntervalMToS"); + return FALSE; + } + if ((pCigParam->sduIntervalSToM < MIN_SDU_INTERVAL) || (pCigParam->sduIntervalSToM > MAX_SDU_INTERVAL)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid sduIntervalSToM"); + return FALSE; + } + if (pCigParam->sca > MAX_SCA) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid sca"); + return FALSE; + } + if (pCigParam->packing > MAX_PACKING) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid packing"); + return FALSE; + } + if (pCigParam->framing > MAX_FRAMING) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid framing"); + return FALSE; + } + if ((pCigParam->transLatMToS < MIN_TRANS_LATENCY) || (pCigParam->transLatMToS > MAX_TRANS_LATENCY)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid transLatMToS"); + return FALSE; + } + if ((pCigParam->transLatSToM < MIN_TRANS_LATENCY) || (pCigParam->transLatSToM > MAX_TRANS_LATENCY)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid transLatSToM"); + return FALSE; + } + if ((pCigParam->numCis < MIN_NUM_CIS) || (pCigParam->numCis > MAX_NUM_CIS)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid numCis"); + return FALSE; + } + + for (unsigned int i = 0; i < pCigParam->numCis; i++) + { + LlCisCisParams_t *pCisParam = &pCigParam->pCisParam[i]; + + if (pCisParam->cisId > MAX_CIS_ID) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid cisId"); + return FALSE; + } + if (pCisParam->sduSizeMToS > MAX_SDU_SIZE) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid sduSizeMToS"); + return FALSE; + } + if (pCisParam->sduSizeSToM > MAX_SDU_SIZE) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid sduSizeSToM"); + return FALSE; + } + if ((pCisParam->phyMToS < MIN_PHY) || (pCisParam->phyMToS > MAX_PHY)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid phyMToS"); + return FALSE; + } + if ((pCisParam->phySToM < MIN_PHY) || (pCisParam->phySToM > MAX_PHY)) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid phySToM"); + return FALSE; + } + if (pCisParam->rteMToS > MAX_RTE) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid rteMToS"); + return FALSE; + } + if (pCisParam->rteSToM > MAX_RTE) + { + LL_TRACE_INFO0("LlIsCigParamsValid Invalid rteSToM"); + return FALSE; + } + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Validate all CIS PHY parameters. + * + * \param pCigParam CIG parameters. + * + * \return True if all PHY are valid, false otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsCigPhyParamsValid(LlCisCigParams_t *pCigParam) +{ + for (unsigned int i = 0; i < pCigParam->numCis; i++) + { + LlCisCisParams_t *pCisParam = &pCigParam->pCisParam[i]; + + if (!llValidatePhySupport(pCisParam->phyMToS, pCisParam->phySToM)) + { + return FALSE; + } + + + if (BB_SYM_PHY_REQ && + (pCisParam->phyMToS != pCisParam->phySToM)) + { + return FALSE; + } + } + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Check if the CIG test parameters are valid or not. + * + * \param pSetCigParamTest Set CIG parameters. + * + * \return True if parameter is valid, False otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsCigTestParamsValid(LlCisCigParamsTest_t *pSetCigParamTest) +{ + /* All the values below are in the valid range. */ + const uint8_t MAX_CIG_ID = 0xEF; + const uint32_t MIN_SDU_INTERVAL = 0x000FF; + const uint32_t MAX_SDU_INTERVAL = 0xFFFFF; + const uint8_t MAX_SCA = 0x07; + const uint8_t MAX_PACKING = 0x01; + const uint8_t MAX_FRAMING = 0x01; + const uint8_t MIN_FT = 0x01; + const uint8_t MAX_FT = 0x1F; + const uint16_t MIN_ISO_INTERVAL = 0x0004; + const uint16_t MAX_ISO_INTERVAL = 0x0C80; + const uint8_t MIN_NUM_CIS = 0x01; + const uint8_t MAX_NUM_CIS = 0x10; + const uint8_t MAX_CIS_ID = 0xEF; + const uint16_t MAX_SDU_SIZE = 0x0FFF; + const uint16_t MAX_PDU_SIZE = 0x0FFB; + const uint8_t MIN_PHY = 0x01; + const uint8_t MAX_PHY = 0x07; + const uint8_t MAX_BN = 0x0F; + + if (pSetCigParamTest->cigId > MAX_CIG_ID) + { + return FALSE; + } + if ((pSetCigParamTest->sduIntervalMToS < MIN_SDU_INTERVAL) || (pSetCigParamTest->sduIntervalMToS > MAX_SDU_INTERVAL)) + { + return FALSE; + } + if ((pSetCigParamTest->sduIntervalSToM < MIN_SDU_INTERVAL) || (pSetCigParamTest->sduIntervalSToM > MAX_SDU_INTERVAL)) + { + return FALSE; + } + if ((pSetCigParamTest->ftMToS < MIN_FT) || (pSetCigParamTest->ftMToS > MAX_FT)) + { + return FALSE; + } + if ((pSetCigParamTest->ftSToM < MIN_FT) || (pSetCigParamTest->ftSToM > MAX_FT)) + { + return FALSE; + } + if ((pSetCigParamTest->isoInterval < MIN_ISO_INTERVAL) || (pSetCigParamTest->isoInterval > MAX_ISO_INTERVAL)) + { + return FALSE; + } + if (pSetCigParamTest->sca > MAX_SCA) + { + return FALSE; + } + if (pSetCigParamTest->packing > MAX_PACKING) + { + return FALSE; + } + if (pSetCigParamTest->framing > MAX_FRAMING) + { + return FALSE; + } + if ((pSetCigParamTest->numCis < MIN_NUM_CIS) || (pSetCigParamTest->numCis > MAX_NUM_CIS)) + { + return FALSE; + } + + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + LlCisCigCisParamsTest_t *pCisParam = &pSetCigParamTest->pCisParam[i]; + + if (pCisParam->cisId > MAX_CIS_ID) + { + return FALSE; + } + if (pCisParam->sduSizeMToS > MAX_SDU_SIZE) + { + return FALSE; + } + if (pCisParam->sduSizeSToM > MAX_SDU_SIZE) + { + return FALSE; + } + if (pCisParam->pduSizeMToS > MAX_PDU_SIZE) + { + return FALSE; + } + if (pCisParam->pduSizeSToM > MAX_PDU_SIZE) + { + return FALSE; + } + if ((pCisParam->phyMToS < MIN_PHY) || (pCisParam->phyMToS > MAX_PHY)) + { + return FALSE; + } + if ((pCisParam->phySToM < MIN_PHY) || (pCisParam->phySToM > MAX_PHY)) + { + return FALSE; + } + if (pCisParam->bnMToS > MAX_BN) + { + return FALSE; + } + if (pCisParam->bnSToM > MAX_BN) + { + return FALSE; + } + } + + + if (pSetCigParamTest->pCisParam->bnMToS > pSetCigParamTest->pCisParam->nse || + pSetCigParamTest->pCisParam->bnSToM > pSetCigParamTest->pCisParam->nse) + { + return FALSE; + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Validate all test cis param PHYs. + * + * \param pSetCigParamTest CIG parameters. + * + * \return True if all PHY are valid, false otherwise. + */ +/*************************************************************************************************/ +static bool_t LlIsCigPhyTestParamsValid(LlCisCigParamsTest_t *pSetCigParamTest) +{ + for (unsigned int i = 0; i < pSetCigParamTest->numCis; i++) + { + LlCisCigCisParamsTest_t *pCisParam = &pSetCigParamTest->pCisParam[i]; + + if (!llValidatePhySupport(pCisParam->phyMToS, pCisParam->phySToM)) + { + return FALSE; + } + + if (BB_SYM_PHY_REQ && + (pCisParam->phyMToS != pCisParam->phySToM)) + { + return FALSE; + } + } + + return TRUE; +} + +/*************************************************************************************************/ +/*! + * \brief Used by a master host to set the parameters of all connected isochronous streams associated with a connected isochronous group in the controller. + * + * \param pCigParam CIG parameters. + * \param pCisHandles Return buffer for the connected isochronous stream handles. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetCigParams(LlCisCigParams_t *pCigParam, uint16_t *pCisHandles) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO1("### LlApi ### LlSetCigParams numCis=%d", pCigParam->numCis); + + memset(pCisHandles, 0, pCigParam->numCis * sizeof(uint16_t)); + + LL_TRACE_INFO1("### LlApi ### LlSetCigParams cigId=%d", pCigParam->cigId); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams sduIntervalMToS=%d", pCigParam->sduIntervalMToS); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams sduIntervalSToM=%d", pCigParam->sduIntervalSToM); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams sca=%d", pCigParam->sca); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams packing=%d", pCigParam->packing); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams framing=%d", pCigParam->framing); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams transLatMToS=%d", pCigParam->transLatMToS); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams transLatSToM=%d", pCigParam->transLatSToM); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams numCis=%d", pCigParam->numCis); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams cisId=%d", pCigParam->pCisParam[0].cisId); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams sduSizeMToS=%d", pCigParam->pCisParam[0].sduSizeMToS); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams sduSizeSToM=%d", pCigParam->pCisParam[0].sduSizeSToM); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams phyMToS=%d", pCigParam->pCisParam[0].phyMToS); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams phySToM=%d", pCigParam->pCisParam[0].phySToM); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams rteMToS=%d", pCigParam->pCisParam[0].rteMToS); + LL_TRACE_INFO1("### LlApi ### LlSetCigParams rteSToM=%d", pCigParam->pCisParam[0].rteSToM); + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsCigParamsValid(pCigParam) == FALSE)) + { + LL_TRACE_INFO0("### LlApi ### LlSetCigParams Invalid Parameters"); + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsCigPhyParamsValid(pCigParam) == FALSE)) + { + LL_TRACE_INFO0("### LlApi ### LlSetCigParams Invalid PHY: Not supported by controller"); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + status = LctrSetCigParam(pCigParam, pCisHandles); + + /* Add the check If the Host attempts to set Connected Isochronous Stream parameters that exceed the maximum supported Connected Isochronous Stream parameters in the Controller, the Controller shall return the error code Unsupported Feature or Parameter Value (0x11).*/ + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used by a master Host to set the parameters of all connected isochronous streams + * associated with a connected isochronous group in the controller for testing purpose. + * + * \param pSetCigParamTest CIG test parameters. + * \param pCisHandles Return buffer for the connected isochronous stream handles. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetCigParamsTest(LlCisCigParamsTest_t *pSetCigParamTest, uint16_t *pCisHandles) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO1("### LlApi ### LlSetCigParamsTest numCis=%d", pSetCigParamTest->numCis); + + memset(pCisHandles, 0, pSetCigParamTest->numCis * sizeof(uint16_t)); + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsCigTestParamsValid(pSetCigParamTest) == FALSE)) + { + LL_TRACE_INFO0("### LlApi ### LlSetCigParamsTest Invalid Parameters"); + return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; + } + + if ((LL_API_PARAM_CHECK == 1) && + (LlIsCigPhyTestParamsValid(pSetCigParamTest) == FALSE)) + { + LL_TRACE_INFO0("### LlApi ### LlSetCigParams Invalid PHY: Not supported by controller"); + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + status = LctrSetCigParamTest(pSetCigParamTest, pCisHandles); + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used by the master host to establish one or more connected isochronous streams. + * + * \param numCis Number of connected isochronous streams. + * \param pCreateCisParam Parameters for create connected isochronous stream. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlCreateCis(uint8_t numCis, LlCisCreateCisParams_t *pCreateCisParam) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO1("### LlApi ### LlCreateCis numCis=%d", numCis); + + if ((lmgrCb.features & LL_FEAT_ISO_HOST_SUPPORT) == 0) + { + LL_TRACE_INFO0("### LlApi ### LlCreateCis ISO host support bit is not enabled"); + return LL_ERROR_CODE_CMD_DISALLOWED; + } + + if ((LL_API_PARAM_CHECK == 1)) + { + for (unsigned int i = 0; i < numCis; i++) + { + if ((pCreateCisParam->pAclHandle[i] >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(pCreateCisParam->pAclHandle[i])) + { + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + if (LctrGetRole(pCreateCisParam->pAclHandle[i]) != LL_ROLE_MASTER) + { + return LL_ERROR_CODE_CMD_DISALLOWED; + } + } + } + status = LctrCreateCis(numCis, pCreateCisParam); + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Removes all the connected isochronous streams which have been set up. + * + * \param cigId Identifier of the connected isochronous group. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlRemoveCig(uint8_t cigId) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO1("### LlApi ### LlRemoveCig CIG_ID=%d", cigId); + + status = LctrRemoveCig(cigId); + + return status; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_slave.c new file mode 100644 index 00000000000..18573d27eb6 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_cis_slave.c @@ -0,0 +1,75 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) master control interface implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_api.h" +#include "lmgr_api.h" +#include "lctr_api_cis_slave.h" +#include "util/bstream.h" +#include "wsf_assert.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include + +/*************************************************************************************************/ +/*! + * \brief Used by the slave host to inform the controller to accept the request for the + * connected isochronous stream. + * + * \param cisHandle Handle of the connected isochronous stream. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlAcceptCisReq(uint16_t cisHandle) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO1("### LlApi ### LlAcceptCisReq cisHandle=%d", cisHandle); + + status = LctrAcceptCisReq(cisHandle); + + return status; +} + +/*************************************************************************************************/ +/*! + * \brief Used by the slave host to inform the controller to reject the request for the + * connected isochronous stream. + * + * \param cisHandle Handle of the connected isochronous stream. + * \param reason Indicate the reason for rejecting the request. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlRejectCisReq(uint16_t cisHandle, uint8_t reason) +{ + uint8_t status = LL_SUCCESS; + + LL_TRACE_INFO2("### LlApi ### LlRejectCisReq cisHandle=%d reason=%d", cisHandle, reason); + + status = LctrRejectCisReq(cisHandle, reason); + + return status; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn.c index 2bef004cd46..9be7e7904e8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) slave parameter interface implementation file. + * \file + * + * \brief Link layer (LL) connection interface implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,6 +27,7 @@ #include "lmgr_api.h" #include "lmgr_api_conn.h" #include "bb_ble_api.h" +#include "pal_radio.h" #include "wsf_assert.h" #include "wsf_cs.h" #include "wsf_math.h" @@ -128,17 +130,61 @@ uint8_t LlGetTxPowerLevel(uint16_t handle, uint8_t type, int8_t *pLevel) /*************************************************************************************************/ /*! - * \brief Set connection's TX power level. + * \brief Get connection's enhanced TX power level and max txPower. + * + * \param handle Connection handle. + * \param phy PHY. + * \param pCurPwr Current transmit power level. + * \param pMaxPwr Max power level. + * + * \return Status error code. + * + */ +/*************************************************************************************************/ +uint8_t LlGetEnhTxPowerLevel(uint16_t handle, uint8_t phy, int8_t *pCurPwr, int8_t *pMaxPwr) +{ + uint8_t result = LL_SUCCESS; + + WSF_CS_INIT(cs); + WSF_CS_ENTER(cs); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + result = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + else if ((phy <= LL_PHY_NONE) || (phy > LL_PC_PHY_TOTAL)) + { + result = LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + else + { + int8_t minPwr; /* Used for getting max power only .*/ + PalRadioGetSupTxPower(&minPwr, pMaxPwr); + *pCurPwr = PalRadioGetActualTxPower(LctrGetPhyTxPowerLevel(handle, phy), FALSE); + } + + WSF_CS_EXIT(cs); + + LL_TRACE_INFO3("### LlApi ### LlGetEnhancedTxPowerLevel, handle=%u, phy=%u, curPower=%d", handle, phy, *pCurPwr); + + return result; +} + +/*************************************************************************************************/ +/*! + * \brief Set connection's TX power level (All PHYs). * * \param handle Connection handle. * \param level Transmit power level. * * \return Status error code. * - * Set the TX power of a connection. + * Set the TX power of a connection (All PHYs). */ /*************************************************************************************************/ -uint8_t LlSetTxPowerLevel(uint16_t handle, int8_t level) +uint8_t LlSetAllPhyTxPowerLevel(uint16_t handle, int8_t level) { uint8_t result = LL_SUCCESS; @@ -163,6 +209,47 @@ uint8_t LlSetTxPowerLevel(uint16_t handle, int8_t level) return result; } +/*************************************************************************************************/ +/*! + * \brief Set connection's TX power level for a PHY. + * + * \param handle Connection handle. + * \param level Transmit power level. + * + * \return Status error code. + * + * Set the TX power of a connection for a PHY. + */ +/*************************************************************************************************/ +uint8_t LlSetPhyTxPowerLevel(uint16_t handle, int8_t level, uint8_t phy) +{ + uint8_t result = LL_SUCCESS; + + LL_TRACE_INFO3("### LlApi ### LlSetPhyTxPowerLevel, handle=%u, level=%d, phy=%u", handle, level, phy); + + WSF_CS_INIT(cs); + WSF_CS_ENTER(cs); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + result = LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + else if (phy > LL_PC_PHY_TOTAL) + { + result = LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + else + { + LctrSetPhyTxPowerLevel(handle, level, phy); + } + + WSF_CS_EXIT(cs); + + return result; +} + /*************************************************************************************************/ /*! * \brief Get connection's channel map. @@ -268,7 +355,7 @@ uint8_t LlDisconnect(uint16_t handle, uint8_t reason) LL_TRACE_INFO2("### LlApi ### LlDisconnect, handle=%u, reason=%u", handle, reason); if ((LL_API_PARAM_CHECK == 1) && - (handle >= (pLctrRtCfg->maxConn + pLctrRtCfg->maxCis * pLctrRtCfg->maxCig))) + (handle >= (LCTR_MAX_HANDLE_INDEX))) { return LL_ERROR_CODE_UNKNOWN_CONN_ID; } @@ -441,7 +528,7 @@ uint8_t LlRemoteConnParamReqReply(uint16_t handle, const LlConnSpec_t *pConnSpec * \param handle Connection handle. * \param reason Reason code. * - * \return None. + * \return Status error code. * * Negative reply to a connection parameter request. */ @@ -585,8 +672,6 @@ uint8_t LlSetDataLen(uint16_t handle, uint16_t txLen, uint16_t txTime) * \param pMaxTxLen Maximum number of payload bytes for a Data PDU * \param pMaxTxTime Maximum microseconds for a Data PDU * - * \return None. - * * Suggested length and microseconds that the local Controller should use to transmit a * single Link Layer Data Channel PDU. */ @@ -650,8 +735,6 @@ uint8_t LlWriteDefaultDataLen(uint16_t maxTxLen, uint16_t maxTxTime) * \param pMaxRxLen Maximum number of payload bytes for a Rx Data PDU * \param pMaxRxTime Maximum microseconds for a Rx Data PDU * - * \return None. - * * Read the Controller's maximum supported payload octets and packet duration times for * transmission and reception. */ @@ -664,7 +747,7 @@ void LlReadMaximumDataLen(uint16_t *pMaxTxLen, uint16_t *pMaxTxTime, uint16_t *p WSF_ASSERT(pMaxTxTime); *pMaxTxLen = WSF_MIN(pLctrRtCfg->maxAclLen, LCTR_MAX_DATA_LEN_MAX); - *pMaxTxTime = LL_DATA_LEN_TO_TIME_1M(*pMaxTxLen); + *pMaxTxTime = LL_DATA_LEN_TO_TIME_1M(*pMaxTxLen, TRUE); *pMaxRxLen = *pMaxTxLen; *pMaxRxTime = *pMaxTxTime; } @@ -831,8 +914,6 @@ uint8_t LlGetAclRxBufs(void) * * \param pData Data buffer * - * \return None. - * * Send an ACL data packet. pData points to an ACL buffer formatted according to [1]; the host * must set the connection handle, flags, and length fields in the buffer. */ @@ -876,8 +957,6 @@ uint8_t *LlRecvAclData(void) * * \param numBufs Number of completed packets. * - * \return None. - * * Indicate that received ACL data buffer has been deallocated. */ /*************************************************************************************************/ @@ -910,7 +989,7 @@ uint8_t LlRequestPeerSca(uint16_t handle) else if ((LL_API_PARAM_CHECK == 1) && ((LctrGetUsedFeatures(handle) & LL_FEAT_SCA_UPDATE) == 0)) { - return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + return LL_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE; } if ((pMsg = (lctrScaReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) @@ -955,7 +1034,7 @@ uint8_t LlModifySleepClockAccuracy(uint8_t action) else /* status = LL_SUCCESS */ { /* Update lmgrCb sca for future connections. */ - switch(action) + switch (action) { case LL_MODIFY_SCA_MORE_ACCURATE: lmgrCb.scaMod++; @@ -995,3 +1074,80 @@ uint8_t LlModifySleepClockAccuracy(uint8_t action) return status; } + +/*************************************************************************************************/ +/*! + * \brief Request change to or read peer txPower + * + * \param handle Connection handle. + * \param delta Requested change. + * \param phy Phy this change requests the change on. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlPowerCtrlReq(uint16_t handle, int8_t delta, uint8_t phy) +{ + lctrMsgPwrCtrlReq_t *pMsg; + + LL_TRACE_INFO3("### LlApi ### LlPowerCtrlReq, handle=%u, delta=%u, phy=%u", handle, delta, phy); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + if ((LL_API_PARAM_CHECK == 1) && + (phy > LL_PC_PHY_TOTAL)) + { + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + else if ((LL_API_PARAM_CHECK == 1) && + ((LctrGetUsedFeatures(handle) & LL_FEAT_POWER_CONTROL_REQUEST) == 0)) + { + return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; + } + + if ((pMsg = (lctrMsgPwrCtrlReq_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL) + { + pMsg->hdr.handle = handle; + pMsg->hdr.dispId = LCTR_DISP_CONN; + pMsg->hdr.event = LCTR_CONN_MSG_API_PWR_CTRL_REQ; + pMsg->delta = delta; + pMsg->phy = phy; + + WsfMsgSend(lmgrPersistCb.handlerId, pMsg); + } + else + { + return LL_ERROR_CODE_MEM_CAP_EXCEEDED; + } + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Set transmit power change reporting enable. + * + * \param handle Connection handle. + * \param enableLocal Enable local reporting. + * \param enableRemote Enable remote reporting. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetTxPowerReporting(uint16_t handle, uint8_t enableLocal, uint8_t enableRemote) +{ + LL_TRACE_INFO3("### LlApi ### LlSetTxPowerReporting, handle=%u, localEnable=%u, remoteEnable=%u", handle, enableLocal, enableRemote); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return lctrSetTxPowerReporting(handle, enableLocal, enableRemote); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master.c index 359a0317581..0ec5c624779 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave parameter interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave parameter interface implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -171,8 +172,6 @@ uint8_t LlCreateConn(const LlInitParam_t *pInitParam, const LlConnSpec_t *pConnS /*! * \brief Cancel a create connection operation. * - * \return None. - * * Cancel a connection before it is established. This function is only used when operating * in master role. This command is used to cancel extended and legacy create connection. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master_ae.c index ddecd4a5cf1..2dd04fca976 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_master_ae.c @@ -1,29 +1,31 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) master extended control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) master extended control interface implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "lctr_api_adv_master_ae.h" #include "lctr_api_init_master_ae.h" #include "lmgr_api_adv_master_ae.h" +#include "lctr_api_conn.h" #include "ll_math.h" #include "wsf_assert.h" #include "wsf_msg.h" @@ -32,46 +34,16 @@ /*************************************************************************************************/ /*! - * \brief Validate Connection spec parameters + * \brief Validate extended connection spec parameters. * - * \param pConnSpec + * \param pParam Pointer to connection spec parameters. * - * \return TRUE if valid, FALSE otherwise. + * \return Status error code. */ /*************************************************************************************************/ -static bool_t llValidateConnSpecParams(const LlConnSpec_t *pParam) +static uint8_t llValidateConnSpecParams(const LlConnSpec_t *pParam) { - /* Connection interval. */ - if ((LL_API_PARAM_CHECK == 1) && - ((pParam->connIntervalMin > pParam->connIntervalMax) || - (pParam->connIntervalMax < pParam->connIntervalMin) || - (pParam->connIntervalMax < HCI_CONN_INTERVAL_MIN) || - (pParam->connIntervalMin < HCI_CONN_INTERVAL_MIN) || - (pParam->connIntervalMax > HCI_CONN_INTERVAL_MAX) || - (pParam->connIntervalMin > HCI_CONN_INTERVAL_MAX) )) - { - return FALSE; - } - - /* Connection latency. */ - if ((LL_API_PARAM_CHECK == 1) && - ((pParam->connLatency > HCI_CONN_LATENCY_MAX))) - { - return FALSE; - } - - /* Supervision timeout. */ - uint32_t supTimeoutMin = ((uint32_t) pParam->connLatency + 1) * LL_CONN_INTERVAL_VAL_TO_US((uint32_t) pParam->connIntervalMax) * 2; - uint32_t supTimeoutUs = LL_SUP_TIMEOUT_VAL_TO_US((uint32_t) pParam->supTimeout); - if ((LL_API_PARAM_CHECK == 1) && - ((supTimeoutUs <= supTimeoutMin) || - (pParam->supTimeout < HCI_SUP_TIMEOUT_MIN) || - (pParam->supTimeout > HCI_SUP_TIMEOUT_MAX))) - { - return FALSE; - } - - return TRUE; + return LctrValidateConnSpec(pParam); } /*************************************************************************************************/ @@ -167,7 +139,7 @@ uint8_t LlExtCreateConn(const LlExtInitParam_t *pInitParam, const LlExtInitScanP if ((LL_API_PARAM_CHECK == 1) && ((pInitParam->initPhys & supportedPhys) != pInitParam->initPhys)) { - LL_TRACE_WARN0("Unsupported PHY bit was set."); + LL_TRACE_WARN0("Unsupported PHY bit was set"); return LL_ERROR_CODE_UNSUPPORTED_FEATURE_PARAM_VALUE; } @@ -181,7 +153,7 @@ uint8_t LlExtCreateConn(const LlExtInitParam_t *pInitParam, const LlExtInitScanP { for (unsigned int i = 0; i < numInitPhyBits; i++) { - if ((!llValidateConnSpecParams(&connSpec[i])) || (!llValidateInitiateScanParams(&scanParam[i]))) + if ((llValidateConnSpecParams(&connSpec[i]) != LL_SUCCESS) || (!llValidateInitiateScanParams(&scanParam[i]))) { return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_slave.c index 606295b568b..1cc0eb5cead 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_conn_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave control interface implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_diag.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_diag.c index fc715e18f26..674d7753b46 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_diag.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_diag.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) test interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) test interface implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -51,7 +52,7 @@ uint8_t LlGetTime(uint32_t *pTime) return LL_ERROR_CODE_CMD_DISALLOWED; } - *pTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); + *pTime = PalBbGetCurrentTime(); return LL_SUCCESS; } @@ -70,5 +71,5 @@ uint8_t LlGetTime(uint32_t *pTime) /*************************************************************************************************/ uint32_t LlCalcDeltaTimeUsec(uint32_t endTime, uint32_t startTime) { - return BB_TICKS_TO_US(endTime - startTime); + return endTime - startTime; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_dtm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_dtm.c index 236e2edb941..95befc6dd92 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_dtm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_dtm.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) DTM interface implementation file. + * \file + * + * \brief Link layer (LL) DTM interface implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -180,8 +181,6 @@ uint8_t llConvertRfChanToChanIdx(uint8_t rfChan) * \param pBuf Buffer to fill. * \param len Number of bytes to fill. * - * \return None. - * * Fill payload with random numbers. */ /*************************************************************************************************/ @@ -262,8 +261,6 @@ static void llBuildTxPkt(uint8_t len, uint8_t pktType, uint8_t *pBuf) * \brief Tx operation end callback. * * \param pOp Tx operation descriptor. - * - * \return None. */ /*************************************************************************************************/ static void llTestTxOpEndCback(BbOpDesc_t *pOp) @@ -346,7 +343,7 @@ static void llTestTxOpEndCback(BbOpDesc_t *pOp) * \return TRUE if next receive should be set up. */ /*************************************************************************************************/ -static bool_t llTestTxCb(BbOpDesc_t *pOp, uint8_t status) +static bool_t llTestTxComplete(BbOpDesc_t *pOp, uint8_t status) { BbBleData_t * const pBle = pOp->prot.pBle; BbBleTestTx_t * const pTx = &pBle->op.testTx; @@ -359,6 +356,12 @@ static bool_t llTestTxCb(BbOpDesc_t *pOp, uint8_t status) return FALSE; } + if (status != BB_STATUS_SUCCESS) + { + LL_TRACE_ERR2("Terminating Tx test mode due to failure, status=%u, numTx=%u", status, llTestCb.rpt.numTx); + return FALSE; + } + if (llTestCb.state == LL_TEST_STATE_TX) { /* Operating parameters have changed. */ @@ -541,7 +544,6 @@ uint8_t LlEnhancedTxTest(uint8_t rfChan, uint8_t len, uint8_t pktType, uint8_t p llTestCb.numPkt = numPkt; pOp->protId = BB_PROT_BLE_DTM; pOp->endCback = llTestTxOpEndCback; - pOp->dueOffsetUsec = 0; /*** BLE General Setup ***/ @@ -564,7 +566,7 @@ uint8_t LlEnhancedTxTest(uint8_t rfChan, uint8_t len, uint8_t pktType, uint8_t p /* Longest packet for dynamic test changes. */ pTx->txLen = WSF_MAX(LL_DTM_MAX_PDU_LEN, LL_ADVB_MAX_LEN); - pTx->testCback = llTestTxCb; + pTx->testCback = llTestTxComplete; pTx->pktInterUsec = llCalcPacketInterval(llTestCb.tx.pduLen, pBle->chan.txPhy, pBle->chan.initTxPhyOptions); if ((pTx->pTxBuf = WsfBufAlloc(pTx->txLen)) == NULL) @@ -612,8 +614,6 @@ uint8_t LlTxTest(uint8_t rfChan, uint8_t len, uint8_t pktType, uint16_t numPkt) * \brief Rx operation completion callback. * * \param pOp Rx operation descriptor. - * - * \return None. */ /*************************************************************************************************/ static void llTestRxOpEndCback(BbOpDesc_t *pOp) @@ -681,7 +681,7 @@ static void llTestRxOpEndCback(BbOpDesc_t *pOp) * \return TRUE if next receive should be set up. */ /*************************************************************************************************/ -static bool_t llTestRxCb(BbOpDesc_t *pBod, uint8_t status) +static bool_t llTestRxComplete(BbOpDesc_t *pBod, uint8_t status) { switch (status) { @@ -799,7 +799,6 @@ uint8_t LlEnhancedRxTest(uint8_t rfChan, uint8_t phy, uint8_t modIdx, uint16_t n llTestCb.numPkt = numPkt; pOp->protId = BB_PROT_BLE_DTM; pOp->endCback = llTestRxOpEndCback; - pOp->dueOffsetUsec = 0; /*** BLE General Setup ***/ @@ -831,7 +830,7 @@ uint8_t LlEnhancedRxTest(uint8_t rfChan, uint8_t phy, uint8_t modIdx, uint16_t n pRx->rxSyncDelayUsec = pLctrRtCfg->dtmRxSyncMs * 1000; pRx->rxLen = WSF_MAX(LL_DTM_MAX_PDU_LEN, LL_ADVB_MAX_LEN); - pRx->testCback = llTestRxCb; + pRx->testCback = llTestRxComplete; uint16_t allocLen = WSF_MAX(pRx->rxLen, BB_FIXED_DATA_PKT_LEN); if ((pRx->pRxBuf = WsfBufAlloc(allocLen)) == NULL) @@ -954,8 +953,6 @@ uint8_t LlSetTxTestErrorPattern(uint32_t pattern) /*************************************************************************************************/ /*! * \brief Test reset handler. - * - * \return None. */ /*************************************************************************************************/ static void llTestResetHandler(void) @@ -969,8 +966,6 @@ static void llTestResetHandler(void) * \brief Test message dispatcher. * * \param pMsg Pointer to message buffer. - * - * \return None. */ /*************************************************************************************************/ static void llTestDisp(lctrMsgHdr_t *pMsg) @@ -1000,8 +995,6 @@ static void llTestDisp(lctrMsgHdr_t *pMsg) /*************************************************************************************************/ /*! * \brief Initialize link layer controller resources for test. - * - * \return None. */ /*************************************************************************************************/ void LlTestInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_master.c index d21ca0fb9da..77fb203ced1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave control interface implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_slave.c index 3f3c837a9d4..c28c16ad21a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_enc_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) slave control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) slave control interface implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -26,7 +27,7 @@ #include "ll_math.h" #include "wsf_msg.h" #include "wsf_trace.h" -#include "stack/platform/include/pal_crypto.h" +#include "pal_crypto.h" #include /*************************************************************************************************/ @@ -57,8 +58,6 @@ uint8_t LlEncrypt(uint8_t *pKey, uint8_t *pData) * \param handle Connection handle. * \param pKey Pointer to new key. * - * \return None. - * * Provide the requested LTK encryption key. This function is only used when operating in * slave mode. */ @@ -103,8 +102,6 @@ uint8_t LlLtkReqReply(uint16_t handle, const uint8_t *pKey) * * \param handle Connection handle. * - * \return None. - * * Requested LTK encryption key not available. This function is only used when operating in * slave mode. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_iso.c new file mode 100644 index 00000000000..b795fddeb62 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_iso.c @@ -0,0 +1,278 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) slave parameter interface implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_api.h" +#include "wsf_cs.h" +#include "wsf_math.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include "util/bstream.h" +#include +#include "lctr_api_iso.h" +#include "lmgr_api_iso.h" + +/*************************************************************************************************/ +/*! + * \brief Get the maximum ISO buffers size. + * + * \return Maximum buffers size in bytes. + */ +/*************************************************************************************************/ +uint16_t LlGetIsoMaxBufSize(void) +{ + LL_TRACE_INFO1("### LlApi ### LlGetIsoMaxBufSize, maxBufSize=%u", pLctrRtCfg->maxIsoSduLen); + + return pLctrRtCfg->maxIsoSduLen; +} + +/*************************************************************************************************/ +/*! + * \brief Get the number of buffers in the LL ISO transmit queue. + * + * \return Number of buffers. + */ +/*************************************************************************************************/ +uint8_t LlGetIsoTxBufs(void) +{ + LL_TRACE_INFO1("### LlApi ### LlGetIsoTxBufs, numBufs=%u", pLctrRtCfg->numIsoTxBuf); + + return pLctrRtCfg->numIsoTxBuf; +} + +/*************************************************************************************************/ +/*! + * \brief Get the number of buffers in the LL ISO receive queue. + * + * \return Number of buffers. + */ +/*************************************************************************************************/ +uint8_t LlGetIsoRxBufs(void) +{ + LL_TRACE_INFO1("### LlApi ### LlGetIsoRxBufs, numBufs=%u", pLctrRtCfg->numIsoRxBuf); + + return pLctrRtCfg->numIsoRxBuf; +} + +/*************************************************************************************************/ +/*! + * \brief Read ISO link Quality stats. + * + * \param handle connection handle. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlReadIsoLinkQual(uint16_t handle, LlIsoLinkQual_t * pStats) +{ + LL_TRACE_INFO1("### LlApi ### LlReadIsoLinkQual, handle=%u", handle); + + return LctrReadIsoLinkQual(handle, pStats); +} + +/*************************************************************************************************/ +/*! + * \brief Initialize LL for use with an audio codec. + */ +/*************************************************************************************************/ +void LlInitCodec(void) +{ + LctrInitCodec(); +} + +/*************************************************************************************************/ +/*! + * \brief Send an ISO data packet. + * + * \param pData Data buffer + * + * Send an ISO data packet. pData points to an ACL buffer formatted according to [1]; the host + * must set the connection handle, flags, and length fields in the buffer. + */ +/*************************************************************************************************/ +void LlSendIsoData(uint8_t *pData) +{ + if (lmgrIsoCb.availTxBuf == 0) + { + LL_TRACE_WARN0("!!! ISO flow control detected; dropping Tx data PDU"); + + /* Drop packet. */ + WsfMsgFree(pData); + return; + } + + LctrTxIso(pData); +} + +/*************************************************************************************************/ +/*! + * \brief Receive an ISO data packet + * + * \return Data buffer. + * + * Receive an ISO data packet. This function returns a pointer to an ISO buffer formatted + * according to [1]. The host must parse the header to determine the connection handle, flags, + * and length fields. If no ISO buffers are available this function returns NULL. + * + * The host must deallocate the buffer by calling WsfMsgFree() and then calling + * LlRecvIsoDataComplete(). + */ +/*************************************************************************************************/ +uint8_t *LlRecvIsoData(void) +{ + return LctrRxIso(); +} + +/*************************************************************************************************/ +/*! + * \brief Indicate that received ISO data buffer has been deallocated + * + * \param numBufs Number of completed packets. + * + * Indicate that received ISO data buffer has been deallocated. + */ +/*************************************************************************************************/ +void LlRecvIsoDataComplete(uint8_t numBufs) +{ + LctrRxIsoComplete(numBufs); +} + +/*************************************************************************************************/ +/*! + * \brief Used to identify and enable the isochronous data path between the host and the + * controller for each connected isochronous or broadcast isochronous stream. + * + * \param handle BIS or CIS handle. + * \param pPktSn Packet sequence number. + * \param pTs Timestamp. + * \param pTimeOffs Time offset. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlReadIsoTxSync(uint16_t handle, uint16_t *pPktSn, uint32_t *pTs, uint32_t *pTimeOffs) +{ + LL_TRACE_INFO1("### LlApi ### LlReadIsoTxSync, handle=%u", handle); + return LctrReadIsoTxSync(handle, pPktSn, pTs, pTimeOffs); +} + +/*************************************************************************************************/ +/*! + * \brief Used to identify and enable the isochronous data path between the host and the + * controller for each connected isochronous stream or broadcast isochronous stream. + * + * \param pSetupDataPath Parameters for setup ISO data path. + */ +/*************************************************************************************************/ +uint8_t LlSetupIsoDataPath(LlIsoSetupDataPath_t *pSetupDataPath) +{ + LL_TRACE_INFO3("### LlApi ### LlSetupIsoDataPath, handle=%u, dpDir=%u, dpId=%u", pSetupDataPath->handle, pSetupDataPath->dpDir, pSetupDataPath->dpId); + + return LctrSetupIsoDataPath(pSetupDataPath); +} + +/*************************************************************************************************/ +/*! + * \brief Used to remove the isochronous data path associated with the + * connected isochronous stream or broadcast isochronous stream. + * + * \param handle CIS or BIS handle. + * \param dpDir Direction of data path to remove. + */ +/*************************************************************************************************/ +uint8_t LlRemoveIsoDataPath(uint16_t handle, uint8_t dpDir) +{ + LL_TRACE_INFO2("### LlApi ### LlRemoveIsoDataPath, handle=%u, dpDir=%u", handle, dpDir); + + return LctrRemoveIsoDataPath(handle, dpDir); +} + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Tx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoTxTest(uint16_t handle, uint8_t pldType) +{ + LL_TRACE_INFO2("### LlApi ### LlIsoTxTest handle=%d pldType=%d", handle, pldType); + + return LctrIsoTxTest(handle, pldType); +} + +/*************************************************************************************************/ +/*! + * \brief Enable ISO Rx test. + * + * \param handle CIS or BIS handle. + * \param pldType Payload type. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoRxTest(uint16_t handle, uint8_t pldType) +{ + LL_TRACE_INFO2("### LlApi ### LlIsoRxTest handle=%d pldType=%d", handle, pldType); + + return LctrIsoRxTest(handle, pldType); +} + +/*************************************************************************************************/ +/*! + * \brief ISO read test counter. + * + * \param handle CIS or BIS handle. + * \param pCtr Test Counter. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoReadTestCounter(uint16_t handle, LlIsoTestCtrs_t *pCtr) +{ + LL_TRACE_INFO1("### LlApi ### LlIsoReadTestCounter handle=%d", handle); + + LctrIsoReadTestCounter(handle, pCtr); + + return LL_SUCCESS; +} + +/*************************************************************************************************/ +/*! + * \brief Terminate ISO Tx or Rx test. + * + * \param handle CIS or BIS handle. + * \param pCtr Test counters. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlIsoTestEnd(uint16_t handle, LlIsoTestCtrs_t *pCtr) +{ + LL_TRACE_INFO1("### LlApi ### LlIsoTestEnd handle=%d", handle); + + return LctrIsoTestEnd(handle, pCtr); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_past.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_past.c index 556beec2056..b41f7b9c019 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_past.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_past.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) Periodic advertising sync transfer interface implementation file. + * \file + * + * \brief Link layer (LL) Periodic advertising sync transfer interface implementation file. + * + * Copyright (c) 2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_pc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_pc.c new file mode 100644 index 00000000000..a67db0f51c3 --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_pc.c @@ -0,0 +1,101 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link layer (LL) power control interface implementation file. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "ll_api.h" +#include "lctr_api_conn.h" +#include "lmgr_api.h" +#include "lmgr_api_conn.h" +#include "wsf_assert.h" +#include "wsf_cs.h" +#include "wsf_msg.h" +#include "wsf_trace.h" +#include +#include "lctr_api_pc.h" + +/*************************************************************************************************/ +/*! + * \brief Set path loss monitoring parameters. + * + * \param handle Handle identifier for connection. + * \param highThresh High extreme threshold. + * \param highHyst High extreme hysteresis. + * \param lowThresh Low extreme threshold. + * \param lowHyst Low extreme hysteresis. + * \param minTime Minimum time spent to trigger event generation. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetPathLossReportingParams(uint16_t handle, uint8_t highThresh, uint8_t highHyst, uint8_t lowThresh, uint8_t lowHyst, uint16_t minTime) +{ + LL_TRACE_INFO0("### LlApi ### LlSetPathLossReportingParams"); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + if (highThresh == LL_PC_PATH_LOSS_UNUSED_HIGH_THRESHOLD) + { + highHyst = 0; + } + + if ((((uint16_t) highThresh + (uint16_t) highHyst) > 0x00FF) || + (lowThresh < lowHyst)) + { + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + if ((lowThresh > highThresh) || + ((lowThresh + lowHyst) > (highThresh - highHyst))) + { + return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; + } + + return lctrSetPathLossReportingParams(handle, highThresh, highHyst, lowThresh, lowHyst, minTime); +} + +/*************************************************************************************************/ +/*! + * \brief Set path loss enable. + * + * \param handle Connection handle. + * \param enable Enable flag. + * + * \return Status error code. + */ +/*************************************************************************************************/ +uint8_t LlSetPathLossReportingEnable(uint16_t handle, uint8_t enable) +{ + LL_TRACE_INFO0("### LlApi ### LlSetPathLossReportingEnable"); + + if ((LL_API_PARAM_CHECK == 1) && + ((handle >= pLctrRtCfg->maxConn) || + !LctrIsConnHandleEnabled(handle))) + { + return LL_ERROR_CODE_UNKNOWN_CONN_ID; + } + + return lctrSetPathLossReportingEnable(handle, enable); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_phy.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_phy.c index ef70602aeee..c0c28308f15 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_phy.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_phy.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) PHY features control interface implementation file. + * \file + * + * \brief Link layer (LL) PHY features control interface implementation file. + * + * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -106,7 +107,7 @@ static uint8_t llValidatePhyPreferences(uint8_t allPhys, uint8_t txPhys, uint8_t * \return TRUE if all specified PHYs are supported. */ /*************************************************************************************************/ -static bool_t llValidatePhySupport(uint8_t txPhys, uint8_t rxPhys) +bool_t llValidatePhySupport(uint8_t txPhys, uint8_t rxPhys) { if (((lmgrCb.features & LL_FEAT_LE_2M_PHY) == 0) && ((txPhys & LL_PHYS_LE_2M_BIT) || (rxPhys & LL_PHYS_LE_2M_BIT))) @@ -123,6 +124,7 @@ static bool_t llValidatePhySupport(uint8_t txPhys, uint8_t rxPhys) return TRUE; } + /*************************************************************************************************/ /*! * \brief Set default PHYs. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_priv.c index 9fe0938fa93..a6b909d4a6e 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_priv.c @@ -1,27 +1,29 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link layer (LL) privacy control interface implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link layer (LL) privacy control interface implementation file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "bb_ble_api_reslist.h" +#include "lctr_api.h" #include "lmgr_api.h" #include "lmgr_api_priv.h" #include "lctr_api_priv.h" @@ -29,6 +31,12 @@ #include "wsf_trace.h" #include "util/bstream.h" +/************************************************************************************************** + Globals +**************************************************************************************************/ +/*! \brief Function pointer for periodic sync pending check. */ +LctrPerSyncPendFn_t LctrMstPerSyncPending; + /*************************************************************************************************/ /*! * \brief Add device to resolving list. @@ -52,7 +60,12 @@ uint8_t LlAddDeviceToResolvingList(uint8_t peerAddrType, const uint8_t *pPeerIde { return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - if ((lmgrCb.advEnabled || lmgrCb.numExtAdvEnabled || lmgrCb.numScanEnabled || lmgrCb.numInitEnabled) && lmgrCb.addrResEna) + if ((lmgrCb.advEnabled || + lmgrCb.numExtAdvEnabled || + lmgrCb.numScanEnabled || + lmgrCb.numInitEnabled || + (LctrMstPerSyncPending && LctrMstPerSyncPending())) + && lmgrCb.addrResEna) { return LL_ERROR_CODE_CMD_DISALLOWED; } @@ -88,7 +101,12 @@ uint8_t LlRemoveDeviceFromResolvingList(uint8_t peerAddrType, const uint8_t *pPe { return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - if ((lmgrCb.advEnabled || lmgrCb.numExtAdvEnabled || lmgrCb.numScanEnabled || lmgrCb.numInitEnabled) && lmgrCb.addrResEna) + if ((lmgrCb.advEnabled || + lmgrCb.numExtAdvEnabled || + lmgrCb.numScanEnabled || + lmgrCb.numInitEnabled || + (LctrMstPerSyncPending && LctrMstPerSyncPending())) + && lmgrCb.addrResEna) { return LL_ERROR_CODE_CMD_DISALLOWED; } @@ -116,7 +134,12 @@ uint8_t LlClearResolvingList(void) { LL_TRACE_INFO0("### LlApi ### LlClearResolvingList"); - if ((lmgrCb.advEnabled || lmgrCb.numExtAdvEnabled || lmgrCb.numScanEnabled || lmgrCb.numInitEnabled) && lmgrCb.addrResEna) + if ((lmgrCb.advEnabled || + lmgrCb.numExtAdvEnabled || + lmgrCb.numScanEnabled || + lmgrCb.numInitEnabled || + (LctrMstPerSyncPending && LctrMstPerSyncPending())) + && lmgrCb.addrResEna) { return LL_ERROR_CODE_CMD_DISALLOWED; } @@ -240,7 +263,11 @@ uint8_t LlSetAddrResolutionEnable(uint8_t enable) { return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - if (lmgrCb.advEnabled || lmgrCb.numExtAdvEnabled || lmgrCb.numScanEnabled || lmgrCb.numInitEnabled) + if (lmgrCb.advEnabled || + lmgrCb.numExtAdvEnabled || + lmgrCb.numScanEnabled || + lmgrCb.numInitEnabled || + (LctrMstPerSyncPending && LctrMstPerSyncPending())) { return LL_ERROR_CODE_CMD_DISALLOWED; } @@ -302,7 +329,12 @@ uint8_t LlSetPrivacyMode(uint8_t peerAddrType, const uint8_t *pPeerIdentityAddr, return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } - if ((lmgrCb.advEnabled || lmgrCb.numExtAdvEnabled || lmgrCb.numScanEnabled || lmgrCb.numInitEnabled) && lmgrCb.addrResEna) + if ((lmgrCb.advEnabled || + lmgrCb.numExtAdvEnabled || + lmgrCb.numScanEnabled || + lmgrCb.numInitEnabled || + (LctrMstPerSyncPending && LctrMstPerSyncPending())) + && lmgrCb.addrResEna) { return LL_ERROR_CODE_CMD_DISALLOWED; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_sc.c index b5c8a523582..a233fdaef1d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_main_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Link layer (LL) secure connections control interface file. + * \file + * + * \brief Link layer (LL) secure connections control interface file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_math.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_math.c index d06c1162c77..5f1cd7da70c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_math.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/ll/ll_math.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Common math utilities generic implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Common math utilities generic implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -37,9 +38,7 @@ static uint32_t wsfRngZ = 521288629; /*!< Z seed for random number generation /*! * \brief Initialize random number seeds. * - * \param seed Pointer to initial seed for random numbers. - * - * \return None. + * \param pSeed Pointer to initial seed for random numbers. */ /*************************************************************************************************/ void LlMathSetSeed(const uint32_t *pSeed) @@ -104,28 +103,54 @@ uint8_t LlMathGetNumBitsSet(uint64_t num) /*************************************************************************************************/ uint32_t LlMathDivideUint32(uint32_t nu32, uint32_t de32) { - uint32_t temp = 1; - uint32_t result = 0; - uint64_t nu = nu32; - uint64_t de = de32; - - while (de <= nu) + #if (defined(__ARM_ARCH_EXT_IDIV__) && (__ARM_ARCH_EXT_IDIV__)) { - de <<= 1; - temp <<= 1; + /* Use divide instruction. */ + return nu32 / de32; } - - while (temp > 1) + #else { - de >>= 1; - temp >>= 1; + /* Use algorithmic divide. */ + + uint32_t temp = 1; + uint32_t result = 0; + uint64_t nu = nu32; + uint64_t de = de32; + + while (de <= nu) + { + de <<= 1; + temp <<= 1; + } - if (nu >= de) + while (temp > 1) { - nu -= de; - result += temp; + de >>= 1; + temp >>= 1; + + if (nu >= de) + { + nu -= de; + result += temp; + } } + + return result; } + #endif +} - return result; +/*************************************************************************************************/ +/*! + * \brief Return result of a division, rounding up. + * + * \param nu32 Numerator of size 32 bits. + * \param de32 Denominator of size 32 bits. + * + * \return Result of a division. + */ +/*************************************************************************************************/ +uint32_t LlMathDivideUint32RoundUp(uint32_t nu32, uint32_t de32) +{ + return LlMathDivideUint32((nu32 + (de32 - 1)), de32); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_events.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_events.c index 0f31a09a883..2d1bdc74a54 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_events.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_events.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link controller manager event implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link controller manager event implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -33,8 +34,6 @@ * \brief Send advertising enable confirm. * * \param status Confirm status. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendAdvEnableCnf(uint8_t status) @@ -55,8 +54,6 @@ void LmgrSendAdvEnableCnf(uint8_t status) * \brief Send scan enable confirm. * * \param status Confirm status. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendScanEnableCnf(uint8_t status) @@ -80,8 +77,6 @@ void LmgrSendScanEnableCnf(uint8_t status) * \param status Confirm status. * \param connHandle Connection handle. * \param numEvents Number of completed events. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendAdvSetTermInd(uint8_t handle, uint8_t status, uint16_t connHandle, uint8_t numEvents) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main.c index 05c1f8293f0..966106a9ca9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager common implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager common implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ #include "ll_math.h" @@ -41,8 +42,6 @@ lmgrCtrlBlk_t lmgrCb; /*! * \brief Set default values. * - * \return None. - * * Restore default values to fields that require initial state after reset. Values that * survive reset are unchanged. */ @@ -83,18 +82,15 @@ void LmgrSetDefaults(void) LL_OP_MODE_FLAG_ENA_MST_CIS_NULL_PDU | /* LL_OP_MODE_FLAG_ENA_SLV_AUX_IND_ADVA | */ /* disabled */ LL_OP_MODE_FLAG_ENA_ADV_CHAN_RAND | + /* LL_OP_MODE_DISABLE_POWER_MONITOR | */ /* disabled */ LL_OP_MODE_FLAG_ENA_LLCP_TIMER; - LhciSetDefaultHciSupCmd(lmgrCb.hciSupCommands); - lmgrCb.chanClass = LL_CHAN_DATA_ALL; } /*************************************************************************************************/ /*! * \brief Increment reset delay counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrIncResetRefCount(void) @@ -105,8 +101,6 @@ void LmgrIncResetRefCount(void) /*************************************************************************************************/ /*! * \brief Decrement reset delay counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrDecResetRefCount(void) @@ -118,8 +112,6 @@ void LmgrDecResetRefCount(void) /*************************************************************************************************/ /*! * \brief Increment whitelist filter enable counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrIncWhitelistRefCount(void) @@ -130,8 +122,6 @@ void LmgrIncWhitelistRefCount(void) /*************************************************************************************************/ /*! * \brief Decrement whitelist filter enable counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrDecWhitelistRefCount(void) @@ -143,8 +133,6 @@ void LmgrDecWhitelistRefCount(void) /*************************************************************************************************/ /*! * \brief Increment periodiclist filter enable counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrIncPeriodiclistRefCount(void) @@ -155,8 +143,6 @@ void LmgrIncPeriodiclistRefCount(void) /*************************************************************************************************/ /*! * \brief Decrement periodiclist filter enable counter. - * - * \return None. */ /*************************************************************************************************/ void LmgrDecPeriodiclistRefCount(void) @@ -242,8 +228,6 @@ bool_t LmgrIsExtCommandAllowed(void) * \brief Build channel remapping table. * * \param pChanParam Channel parameters. - * - * \return None. */ /*************************************************************************************************/ void LmgrBuildRemapTable(lmgrChanParam_t *pChanParam) @@ -346,8 +330,6 @@ uint8_t LmgrSelectNextChannel(lmgrChanParam_t *pChanParam, uint16_t eventCounter uint16_t unmapChan = LL_MATH_MOD_37(prn_e & 0xFFFF); - pChanParam->lastChanIdx = unmapChan; - /* remappingIndex */ if (!((UINT64_C(1) << unmapChan) & pChanParam->chanMask)) @@ -395,7 +377,7 @@ uint8_t LmgrSelectNextSubEvtChannel(lmgrChanParam_t *pChanParam) /* Subevent pseudo random number generator. */ prn = lmgrCalcPerm(prn); - prn = lmgrCalcMAM(prn, pChanParam->chIdentifier); /* prn is prnSubEvent_lu*/ + prn = lmgrCalcMAM(prn, pChanParam->chIdentifier); /* prn is prnSubEvent_lu */ pChanParam->prnLast = prn; @@ -413,15 +395,3 @@ uint8_t LmgrSelectNextSubEvtChannel(lmgrChanParam_t *pChanParam) return pChanParam->chanRemapTbl[subEvtIdx]; } - -/*************************************************************************************************/ -/*! - * \brief Lmgr Read HCI Supported cmd - * - * \return Supported command bitmask table. - */ -/*************************************************************************************************/ -uint8_t * LmgrReadHciSupCmd(void) -{ - return lmgrCb.hciSupCommands; -} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_master_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_master_ae.c index fdc2855634b..8431c817781 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_master_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_master_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager extended scan implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager extended scan implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -30,8 +31,6 @@ * \brief Send extended scan enable confirm. * * \param status Confirm status. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendExtScanEnableCnf(uint8_t status) @@ -68,8 +67,6 @@ void LmgrSendExtScanEnableCnf(uint8_t status) /*************************************************************************************************/ /*! * \brief Send scan timeout indication. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendScanTimeoutInd(void) @@ -90,8 +87,6 @@ void LmgrSendScanTimeoutInd(void) * \brief Send extended advertising report indication. * * \param pEvt Extended advertising report event. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendExtAdvRptInd(LlExtAdvReportInd_t *pEvt) @@ -132,8 +127,6 @@ void LmgrSendPerAdvRptInd(LlPerAdvReportInd_t *pEvt) * \param status Confirm status. * \param handle Sync handle. * \param pEvt Periodic advertising sync established event. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendSyncEstInd(uint8_t status, uint16_t handle, lmgrPerAdvSyncEstdInd_t *pEvt) @@ -165,8 +158,6 @@ void LmgrSendSyncEstInd(uint8_t status, uint16_t handle, lmgrPerAdvSyncEstdInd_t * \brief Send periodic advertising sync lost event. * * \param handle Sync handle. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendSyncLostInd(uint16_t handle) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_slave_ae.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_slave_ae.c index f30900ea39f..c939415732d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_slave_ae.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_adv_slave_ae.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager extended advertising implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager extended advertising implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -32,8 +33,6 @@ * * \param handle Advertising handle. * \param status Confirm status. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendExtAdvEnableCnf(uint8_t handle, uint8_t status) @@ -76,8 +75,6 @@ void LmgrSendExtAdvEnableCnf(uint8_t handle, uint8_t status) * \param handle Advertising handle. * \param scanAddrType Scanner address type. * \param scanAddr Scanner address. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendScanReqReceivedInd(uint8_t handle, uint8_t scanAddrType, uint64_t scanAddr) @@ -108,8 +105,6 @@ void LmgrSendScanReqReceivedInd(uint8_t handle, uint8_t scanAddrType, uint64_t s * * \param handle Advertising handle. * \param status Confirm status. - * - * \return None. */ /*************************************************************************************************/ void LmgrSendPeriodicAdvEnableCnf(uint8_t handle, uint8_t status) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_cis_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_cis_master.c new file mode 100644 index 00000000000..0d5d5ec5d3d --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_cis_master.c @@ -0,0 +1,60 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link manager connected isochronous stream master role implementation file. + * + * Copyright (c) 2013-2018 ARM Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "lmgr_api_cis_master.h" +#include "lctr_api.h" +#include + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Master role device parameters. */ +lmgrCisMstCtrlBlk_t lmgrCisMstCb; + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer manager master mode resources. + */ +/*************************************************************************************************/ +void LmgrMstCisInit(void) +{ + memset(&lmgrCisMstCb, 0, sizeof(lmgrCisMstCb)); + + lmgrCisMstCb.maxNumCis = pLctrRtCfg->maxCis; + + /* lmgrCisMstCb.numCisPend = 0; */ /* Clear by default */ +} + +/*************************************************************************************************/ +/*! + * \brief Get the maximum number of CIS. + * + * \return Maximum number of CIS. + */ +/*************************************************************************************************/ +uint8_t LmgrMstCisGetMaxNumCis(void) +{ + return lmgrCisMstCb.maxNumCis; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_conn.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_conn.c index 2bc8c3c946d..74b2e09fe86 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_conn.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_conn.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager connection implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager connection implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,8 +37,6 @@ lmgrConnCtrlBlk_t lmgrConnCb; /*************************************************************************************************/ /*! * \brief Initialize link layer manager connection resources. - * - * \return None. */ /*************************************************************************************************/ void LmgrConnInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_iso.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_iso.c new file mode 100644 index 00000000000..6cf9068eebd --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_iso.c @@ -0,0 +1,52 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief Link manager connected isochronous stream implementation file. + * + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "bb_ble_api.h" +#include "lctr_api.h" +#include +#include "lmgr_api_iso.h" + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Isochronous control block. */ +lmgrIsoCtrlBlk_t lmgrIsoCb; + +/*************************************************************************************************/ +/*! + * \brief Initialize link layer manager connection resources. + */ +/*************************************************************************************************/ +void LmgrIsoInit(void) +{ + memset(&lmgrIsoCb, 0, sizeof(lmgrIsoCb)); + + lmgrIsoCb.availTxBuf = pLctrRtCfg->numIsoTxBuf; + lmgrIsoCb.availRxBuf = pLctrRtCfg->numIsoRxBuf; + + lmgrIsoCb.allPhys = LL_ALL_PHY_TX_PREFERENCE_BIT | LL_ALL_PHY_RX_PREFERENCE_BIT; + lmgrIsoCb.rxPhys = LL_PHYS_NONE; + lmgrIsoCb.txPhys = LL_PHYS_NONE; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_master.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_master.c index 0397559ef57..0f59cb71619 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_master.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_master.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager master role implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager master role implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ lmgrMstScanCtrlBlk_t lmgrMstScanCb; /*************************************************************************************************/ /*! * \brief Initialize link layer manager master mode resources. - * - * \return None. */ /*************************************************************************************************/ void LmgrMstInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_priv.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_priv.c index b31db6420ba..9415685dbe6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_priv.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_priv.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager privacy implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager privacy implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ lmgrPrivCtrlBlk_t lmgrPrivCb; /*************************************************************************************************/ /*! * \brief Initialize link layer manager privacy resources. - * - * \return None. */ /*************************************************************************************************/ void LmgrPrivInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_sc.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_sc.c index 921564fa7c0..5d82b156ee9 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_sc.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_sc.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager secure connections implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager secure connections implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -35,8 +36,6 @@ lmgrScCtrlBlk_t lmgrScCb; /*************************************************************************************************/ /*! * \brief Initialize link layer manager connection resources. - * - * \return None. */ /*************************************************************************************************/ void LmgrScInit(void) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_slave.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_slave.c index 56eca1ba055..bf67cd28231 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_slave.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/lmgr/lmgr_main_slave.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Link manager slave role implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Link manager slave role implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,16 +37,14 @@ lmgrSlvAdvCtrlBlk_t lmgrSlvAdvCb; /*************************************************************************************************/ /*! * \brief Initialize link layer manager slave mode resources. - * - * \return None. */ /*************************************************************************************************/ void LmgrSlvInit(void) { static const lmgrAdvParam_t defAdvParam = { - .advInterMin = 0x0800, - .advInterMax = 0x0800, + .advInterMinUsec = BB_BLE_TO_US(0x0800), + .advInterMaxUsec = BB_BLE_TO_US(0x0800), .advType = LL_ADV_CONN_UNDIRECT, .ownAddrType = LL_ADDR_PUBLIC, .peerAddrType = LL_ADDR_PUBLIC, @@ -59,9 +58,4 @@ void LmgrSlvInit(void) lmgrSlvAdvCb.defTxPhyOpts = BB_PHY_OPTIONS_BLE_S8; lmgrSlvAdvCb.advParam = defAdvParam; - /* The maximum adv interval is 0x4000 and it times 625 still fits in uint32_t. */ - /* coverity[overflow_before_widen] */ - lmgrSlvAdvCb.advParam.advInterMin = BB_BLE_TO_BB_TICKS(lmgrSlvAdvCb.advParam.advInterMin); - /* coverity[overflow_before_widen] */ - lmgrSlvAdvCb.advParam.advInterMax = BB_BLE_TO_BB_TICKS(lmgrSlvAdvCb.advParam.advInterMax); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_ble.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_ble.c index 5f1677378ee..0c12985f63f 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_ble.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_ble.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief BLE protocol scheduler implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief BLE protocol scheduler implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -67,13 +68,13 @@ uint32_t SchBleCalcDataPktDurationUsec(uint8_t phy, uint16_t len) switch (phy) { case BB_PHY_BLE_1M: - duration += LL_DATA_LEN_TO_TIME_1M(len); + duration += LL_DATA_LEN_TO_TIME_1M(len, TRUE); break; case BB_PHY_BLE_2M: - duration += LL_DATA_LEN_TO_TIME_2M(len); + duration += LL_DATA_LEN_TO_TIME_2M(len, TRUE); break; case BB_PHY_BLE_CODED: - duration += LL_DATA_LEN_TO_TIME_CODED_S8(len); + duration += LL_DATA_LEN_TO_TIME_CODED_S8(len, TRUE); break; } @@ -122,8 +123,10 @@ uint32_t SchBleCalcAdvPktDurationUsec(uint8_t phy, uint8_t phyOptions, uint16_t * \param fragLen Fragmentation length. * \param addMafDelay MAF offset to add on top of MAF. * \param len Data length to calculate. - * \param worseCase True if we want to calculate the worst case, false for predicted case. + * \param worstCase True if we want to calculate the worst case, false for predicted case. * \param phyOptions Phy option to use when calculating coded timing. + * + * \return Advertising duration in usec. */ /*************************************************************************************************/ uint32_t SchBleCalcPerAdvDurationUsec(uint8_t txPhy, uint8_t fragLen, uint16_t addMafDelay, uint16_t len, bool_t worstCase, uint8_t phyOptions) @@ -194,14 +197,12 @@ uint32_t SchBleCalcAuxPktDurationUsec(uint8_t phy, uint8_t phyOptions, uint16_t * \param pBod Operation to compute duration. * \param fragLen Fragmentation length. * - * \return None. - * * Compute all the actions time and assign the duration of the given BOD. */ /*************************************************************************************************/ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) { - uint32_t usec = 0; + uint32_t minDurUsec = 0; WSF_ASSERT(pBod->protId == BB_PROT_BLE); @@ -219,32 +220,32 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) { case BB_PHY_BLE_1M: default: - usec = LL_ADVB_MAX_TIME_1M; + minDurUsec = LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec = LL_ADVB_MAX_TIME_S8; + minDurUsec = LL_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxReqBuf) { - usec += LL_BLE_TIFS_US; + minDurUsec += LL_BLE_TIFS_US; /* Coded PHY doesn't have pTxReqBuf on primary channel. BB_PHY_OPTIONS_DEFAULT is OK. */ - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen); + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen); if (pAdv->pRxRspBuf) { - usec += LL_BLE_TIFS_US; + minDurUsec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: - usec += LL_ADVB_MAX_TIME_1M; + minDurUsec += LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec += LL_ADVB_MAX_TIME_S8; + minDurUsec += LL_ADVB_MAX_TIME_S8; break; } } @@ -267,28 +268,28 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) WSF_ASSERT(numChan > 0); - usec = (numChan - 1) * SchBleGetAlignedAuxOffsUsec(pktDuration + BbGetSchSetupDelayUs()); - usec += pktDuration; /* For the last channel. */ + minDurUsec = (numChan - 1) * SchBleGetAlignedAuxOffsUsec(pktDuration + BbGetSchSetupDelayUs()); + minDurUsec += pktDuration; /* For the last channel. */ if (pAdv->pRxReqBuf) { - usec += (LL_BLE_TIFS_US * numChan); + minDurUsec += (LL_BLE_TIFS_US * numChan); switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: - usec += (LL_ADVB_MAX_TIME_1M * numChan); + minDurUsec += (LL_ADVB_MAX_TIME_1M * numChan); break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec += (LL_ADVB_MAX_TIME_S8 * numChan); + minDurUsec += (LL_ADVB_MAX_TIME_S8 * numChan); break; } if (pAdv->pTxRspBuf) { - usec += (LL_BLE_TIFS_US * numChan); + minDurUsec += (LL_BLE_TIFS_US * numChan); /* Coded PHY doesn't have pTxRspBuf on primary channel. BB_PHY_OPTIONS_DEFAULT is OK. */ - usec += (SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen) * numChan); + minDurUsec += (SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen) * numChan); } } break; @@ -304,41 +305,41 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) { case BB_PHY_BLE_1M: default: - usec = LL_EXT_ADVB_MAX_TIME_1M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: - usec = LL_EXT_ADVB_MAX_TIME_2M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Setting min & max duration differently to avoid conflict with other BOD's. */ /* Min = 3.8ms for normal size(up to 50 bytes) */ /* Max = 17.4ms for maximum size(up to 255 bytes) */ /* When RX data size is larger than 50 bytes, it may stomp on the next high priority BOD's. */ - // TODO: We need HW support(Radio interrupt when packet header is received) to properly fix the problem. - usec = LL_EXT_ADVB_NORMAL_TIME_S8; + /* TODO: We need HW support(Radio interrupt when packet header is received) to properly fix the problem. */ + minDurUsec = LL_EXT_ADVB_NORMAL_TIME_S8; pBod->maxDurUsec = LL_EXT_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxAuxReqBuf) { - usec += LL_BLE_TIFS_US; - /*if TIFS has preference, it should use this value. Otherwise, it will assume longest time, codes S8. */ - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, pAdv->txAuxReqLen); + minDurUsec += LL_BLE_TIFS_US; + /* If TIFS has preference, it should use this value. Otherwise, it will assume longest time, codes S8. */ + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, pAdv->txAuxReqLen); - usec += LL_BLE_TIFS_US; + minDurUsec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: - usec += LL_EXT_ADVB_MAX_TIME_1M; + minDurUsec += LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: - usec += LL_EXT_ADVB_MAX_TIME_2M; + minDurUsec += LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec += LL_EXT_ADVB_MAX_TIME_S8; + minDurUsec += LL_EXT_ADVB_MAX_TIME_S8; break; } } @@ -350,24 +351,24 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) { case BB_PHY_BLE_1M: default: - usec = LL_EXT_ADVB_MAX_TIME_1M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: - usec = LL_EXT_ADVB_MAX_TIME_2M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec = LL_EXT_ADVB_MAX_TIME_S8; + minDurUsec = LL_EXT_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxAuxReqBuf) { - usec += LL_BLE_TIFS_US; + minDurUsec += LL_BLE_TIFS_US; /* Ff TIFS has preference, it should use this value. Otherwise, it will assume longest time, coded S8. */ - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); /* aux_conn_req */ - usec += LL_BLE_TIFS_US; + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); /* aux_conn_req */ + minDurUsec += LL_BLE_TIFS_US; /* Assume longest time, coded S8. */ - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_RSP_PDU_LEN); /* aux_conn_rsp */ + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_RSP_PDU_LEN); /* aux_conn_rsp */ } } break; @@ -383,25 +384,25 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) if (pAuxAdv->pRxAuxReqBuf) /* Scannable advertising */ { - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_NO_CHAIN_HDR_LEN); - usec += LL_BLE_TIFS_US; + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_NO_CHAIN_HDR_LEN); + minDurUsec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: - usec += LL_EXT_ADVB_MAX_TIME_1M; + minDurUsec += LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: - usec += LL_EXT_ADVB_MAX_TIME_2M; + minDurUsec += LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ - usec += LL_EXT_ADVB_MAX_TIME_S8; + minDurUsec += LL_EXT_ADVB_MAX_TIME_S8; break; } - usec += LL_BLE_TIFS_US; + minDurUsec += LL_BLE_TIFS_US; } extHeadLen = WSF_MAX(pAuxAdv->txAuxAdvPdu[0].len, SCH_AUX_ADV_NO_CHAIN_HDR_LEN); @@ -414,36 +415,35 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) if (dataLen <= maxDataBytesNoChain) { - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, extHeadLen + dataLen); + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, extHeadLen + dataLen); } else { uint16_t remDataLen; uint16_t numFragWithAuxPtr = dataLen / maxDataBytesWithChain; - usec += numFragWithAuxPtr * SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_W_CHAIN_HDR_LEN + maxDataBytesWithChain); - usec += numFragWithAuxPtr * LL_BLE_MAFS_US; + minDurUsec += numFragWithAuxPtr * SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_W_CHAIN_HDR_LEN + maxDataBytesWithChain); + minDurUsec += numFragWithAuxPtr * LL_BLE_MAFS_US; remDataLen = dataLen - (numFragWithAuxPtr * maxDataBytesWithChain); if (remDataLen) { - usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_NO_CHAIN_HDR_LEN + remDataLen); + minDurUsec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, SCH_AUX_ADV_NO_CHAIN_HDR_LEN + remDataLen); } } - break; } case BB_BLE_OP_SLV_PER_ADV_EVENT: { /* The calculation for the periodic event is estimate here because we do not have information how optional header bytes are going to be filled later. */ - uint16_t dataLen = 0; + uint16_t dataLen = LL_EXT_ADV_HDR_MAX_LEN; if (pBod->pDataLen) { - dataLen = *pBod->pDataLen; + dataLen = WSF_MAX(dataLen, *pBod->pDataLen); } - usec = SchBleCalcPerAdvDurationUsec(pBle->chan.txPhy, 0, 0, dataLen, FALSE, pBle->chan.initTxPhyOptions); + minDurUsec = SchBleCalcPerAdvDurationUsec(pBle->chan.txPhy, 0, 0, dataLen, FALSE, pBle->chan.initTxPhyOptions); break; } case BB_BLE_OP_MST_PER_SCAN_EVENT: @@ -452,18 +452,18 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) { case BB_PHY_BLE_1M: default: - usec = LL_EXT_ADVB_MAX_TIME_1M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: - usec = LL_EXT_ADVB_MAX_TIME_2M; + minDurUsec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Setting min & max duration differently so that other BOD's can run after minDuration. */ /* Min = 3.8ms for normal size(up to 50 bytes) */ /* Max = 17.4ms for maximum size(up to 255 bytes) */ /* When RX data size is larger than 50 bytes, it may stomp on the next high priority BOD's. */ - // TODO: We need HW support(Radio interrupt when packet header is received) to properly fix the problem. - usec = LL_EXT_ADVB_NORMAL_TIME_S8; + /* TODO: We need HW support (Radio interrupt when packet header is received) to properly fix the problem. */ + minDurUsec = LL_EXT_ADVB_NORMAL_TIME_S8; pBod->maxDurUsec = LL_EXT_ADVB_MAX_TIME_S8; break; } @@ -471,11 +471,11 @@ void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod, uint8_t fragLen) } default: - usec = 0; + minDurUsec = 0; break; } - pBod->minDurUsec = usec; + pBod->minDurUsec = minDurUsec; } /*************************************************************************************************/ @@ -499,7 +499,7 @@ bool_t SchBleGetNextMstConnDueTime(uint32_t *pDueTime) if ((pCur->protId == BB_PROT_BLE) && (pCur->prot.pBle->chan.opType == BB_BLE_OP_MST_CONN_EVENT)) { - *pDueTime = pCur->due; + *pDueTime = pCur->dueUsec; return TRUE; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_rm.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_rm.h index 42924e4448f..72342806fb1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_rm.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_rm.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal scheduler resource manager interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal scheduler resource manager interface file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -45,17 +46,17 @@ extern "C" { #define SCH_RM_DIV_PREF_PER(n) ((uint32_t)(((uint64_t)(n) * UINT64_C(1717987)) >> 34)) /*! \brief Minimum offset unit of reservation manager in microseconds. (Half of minimum isochronous interval) */ -#define SCH_RM_MIN_OFFSET_UNIT 2500 +#define SCH_RM_MIN_OFFSET_UNIT_US 2500 -/*! \brief Distance between common reservation and uncommon reservation. */ -#define SCH_RM_OFFSET_UNCOMMON 3750 +/*! \brief Default distance in microseconds between common reservation and uncommon reservation. */ +#define SCH_RM_OFFSET_UNCOMMON_US 3750 + +/*! \brief Margin in microseconds from the duration of the common reservation to uncommon reservation. */ +#define SCH_RM_MARGIN_UNCOMMON_US 50 /*! \brief Maximum depth to be searched between intervals. (4 means 16 times(2^4) */ #define SCH_RM_MAX_SEARCH_DEPTH 4 -/*! \brief Maximum span of scheduler elements. */ -#define SCH_RM_MAX_SPAN 0x80000000 - /************************************************************************************************** Data Types **************************************************************************************************/ @@ -65,8 +66,9 @@ typedef struct { uint8_t handle; /*!< Reservation handle. */ bool_t commIntUsed; /*!< Reservation is controlled by common interval. */ - uint8_t offsetBit; /*! < Offset bit location. */ + uint8_t offsetBit; /*!< Offset bit location. */ uint32_t interUsec; /*!< Interval in microseconds. */ + uint32_t durUsec; /*!< Duration in microseconds. */ GetRefTimeCb_t refTimeCb; /*!< Callback function to get reference time of the handle. */ } schRmRsvn_t; @@ -94,6 +96,7 @@ extern SchRmCb_t schRmCb; **************************************************************************************************/ void schRmSortListDescending(uint32_t item[], uint8_t numItems); +uint8_t schRmIntCalculateDepth(uint32_t intLarge, uint32_t intSmall); #ifdef __cplusplus }; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_tm.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_tm.h new file mode 100644 index 00000000000..6929e21674f --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_int_tm.h @@ -0,0 +1,88 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief BLE topology manager internal interface file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#ifndef SCH_INT_TM_H +#define SCH_INT_TM_H + +#include "sch_api.h" +#include "sch_api_ble.h" +#include "ll_math.h" +#include "cfg_mac_ble.h" +#include "pal_bb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +/*! \brief Maximum link amount. */ +#define SCH_TM_MAX_LINK (LL_MAX_CONN + LL_MAX_PER_SCAN + LL_MAX_CIG) + +/*! \brief Decide if given time is in the future compared to reference time. */ +#define SCH_TM_IS_IN_FUTURE(x, ref) (BbGetTargetTimeDelta(x, ref) > 0) + +/*! \brief Decide if given time is in the past compared to reference time. */ +#define SCH_TM_IS_IN_PAST(x, ref) (BbGetTargetTimeDelta(ref, x) > 0) + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Topology link descriptor. */ +typedef struct +{ + bool_t enabled; /*!< TRUE if the link is enabled. */ + bool_t movable; /*!< TRUE if the link is movable. */ + uint32_t interUsec; /*!< Interval in microseconds. */ + uint32_t durUsec; /*!< Duration in microseconds. */ + GetTopRefTimeCb_t refTimeCb; /*!< Callback function to get reference time of the handle. */ +} schTmLink_t; + +/*! \brief Topology manager control block. */ +typedef struct +{ + schTmLink_t tlink[SCH_TM_MAX_LINK]; /*!< Information for each topology link. */ +} SchTmCb_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +extern SchTmCb_t schTmCb; + +/************************************************************************************************** + Function Declarations +**************************************************************************************************/ + +uint32_t SchTmGetFirstAnchor(uint32_t refTime, uint32_t defOffsUsec, uint32_t interUsec, uint32_t durUsec); +bool_t SchTmCheckConflict(uint32_t refBegin, uint32_t interUsec, uint32_t durUsec); + +#ifdef __cplusplus +}; +#endif + +#endif /* SCH_INT_TM_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_rm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_rm.c index 3a0df954cef..812d7ce88f4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_rm.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_rm.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Operation list maintenance implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Operation list maintenance implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -55,6 +56,7 @@ /*************************************************************************************************/ #include "sch_int_rm.h" +#include "sch_int_tm.h" #include "wsf_assert.h" #include "wsf_math.h" #include @@ -69,8 +71,8 @@ WSF_CT_ASSERT((SCH_RM_MAX_RSVN <= 32)); /*! \brief Total number of reservation bins. */ #define SCH_RM_MAX_RSVN_BINS ((sizeof(schRmRsvnRatio)/sizeof(schRmRsvnRatio[0])) - 1) -/*! \brief Nominal window widening in microseconds in slave scheduler. */ -#define SCH_RM_SLAVE_WW_USECS 100 +/*! \brief Maximum number of attempts to add reservation. */ +#define SCH_RM_ADD_MAX_ATTEMPTS 3 /************************************************************************************************** Global Variables @@ -245,7 +247,7 @@ static bool_t schRmCheckRsvnCapacity(uint8_t handle, uint32_t interUsec) * \return Depth between intervals. */ /*************************************************************************************************/ -static uint8_t schRmIntCalculateDepth(uint32_t intLarge, uint32_t intSmall) +uint8_t schRmIntCalculateDepth(uint32_t intLarge, uint32_t intSmall) { uint8_t x; uint8_t depth = 0; @@ -253,7 +255,7 @@ static uint8_t schRmIntCalculateDepth(uint32_t intLarge, uint32_t intSmall) WSF_ASSERT(intLarge > intSmall); - for (x = 0; (x < SCH_RM_MAX_SEARCH_DEPTH) && (tmpInt > SCH_RM_MIN_OFFSET_UNIT); x++) + for (x = 0; (x < SCH_RM_MAX_SEARCH_DEPTH) && (tmpInt > SCH_RM_MIN_OFFSET_UNIT_US); x++) { tmpInt >>= 1; if (tmpInt == intSmall) @@ -272,16 +274,35 @@ static uint8_t schRmIntCalculateDepth(uint32_t intLarge, uint32_t intSmall) * * \param handle Client defined reservation handle. * \param depth Offset depth of the interval of the handle compared to maxConInt. + * \param interUsec Interval of the reservation in microseconds. + * \param durUsec Duration of the reservation in microseconds. * * \return TRUE if update was successful, FALSE otherwise.. */ /*************************************************************************************************/ -static bool_t schRmIntAddRmOffset(uint8_t handle, uint8_t depth) +static bool_t schRmIntAddRmOffset(uint8_t handle, uint8_t depth, uint32_t interUsec, uint32_t durUsec) { bool_t updated = FALSE; - uint8_t x, y, numBitsOn; + uint32_t offsetUnitUs = schRmCb.commonInt >> schRmCb.offsetDepth; + uint32_t tmpRmStatus = schRmCb.rmStatus; + uint8_t numBitsPerRes = 1; /* Number of bit offsets to be occupied by the reservation. */ + uint8_t x, y, z, numBitsOn; WSF_ASSERT(schRmCb.offsetDepth >= depth); + WSF_ASSERT(durUsec < schRmCb.commonInt); + + /* If duration is 12ms while offset unit is 5ms, the reservation will occupy 3 consecutive offset bits. */ + while (durUsec >= offsetUnitUs) + { + numBitsPerRes++; + durUsec -= offsetUnitUs; + } + + if (numBitsPerRes > 1) + { + /* Need to duplicate rmStatus to check if the reservation has conflict with lowest bit offset. */ + tmpRmStatus |= (tmpRmStatus << (1 << schRmCb.offsetDepth)); + } for (x = 0; x < (1 << (schRmCb.offsetDepth - depth)); x++) { @@ -290,28 +311,48 @@ static bool_t schRmIntAddRmOffset(uint8_t handle, uint8_t depth) numBitsOn = 0; for (y = 0; y < (1 << depth); y++) { - if ((schRmCb.rmStatus >> ((1 << (schRmCb.offsetDepth - depth)) * y + x)) & 0x01) + for (z = 0; z < numBitsPerRes; z++) { - numBitsOn++; + if ((tmpRmStatus >> ((1 << (schRmCb.offsetDepth - depth)) * y + x + z)) & 0x01) + { + numBitsOn++; + } } } /* Found available offset bit(s). */ if (numBitsOn == 0) { + /* Check conflict with TM links. */ + if (schRmCb.rsvn[schRmCb.refHandle].refTimeCb != NULL) + { + uint32_t rmRefTime = schRmCb.rsvn[schRmCb.refHandle].refTimeCb(schRmCb.refHandle, NULL); + uint32_t targetTime = rmRefTime + (offsetUnitUs * x); + + if (SchTmCheckConflict(targetTime, interUsec, durUsec)) + { + /* Conflict is found, move on to next offset bits. */ + continue; + } + } + /* Set all the bits */ for (y = 0; y < (1 << depth); y++) { - schRmCb.rmStatus |= (0x01 << ((1 << (schRmCb.offsetDepth - depth)) * y + x)); + for (z = 0; z < numBitsPerRes; z++) + { + schRmCb.rmStatus |= (0x01 << ((1 << (schRmCb.offsetDepth - depth)) * y + x + z)); + } } schRmCb.rsvn[handle].offsetBit = x; schRmCb.rsvn[handle].commIntUsed = TRUE; updated = TRUE; - LL_TRACE_WARN2("schRmIntAddRmOffset, handle = %u, offsetDepth = %u", handle, schRmCb.offsetDepth); - LL_TRACE_WARN1(" rmStatus = 0x%x", schRmCb.rmStatus); - LL_TRACE_WARN1(" commonInt = %u", schRmCb.commonInt); + LL_TRACE_INFO2("schRmIntAddRmOffset, handle = %u, offsetDepth = %u", handle, schRmCb.offsetDepth); + LL_TRACE_INFO1(" rmStatus = 0x%x", schRmCb.rmStatus); + LL_TRACE_INFO1(" commonInt = %u", schRmCb.commonInt); + LL_TRACE_INFO1(" offsetBit = %u", schRmCb.rsvn[handle].offsetBit); break; } } @@ -325,42 +366,71 @@ static bool_t schRmIntAddRmOffset(uint8_t handle, uint8_t depth) * * \param depth Offset depth to be increased. * - * \return None. + * \return TRUE if offset depth was increased successfully, FALSE otherwise.. */ /*************************************************************************************************/ -static void schRmIntIncOffsetDepth(uint8_t depth) +static bool_t schRmIntIncOffsetDepth(uint8_t depth) { - uint32_t tmpStatus = schRmCb.rmStatus; - uint8_t x, handle; + uint8_t y, z, handle; + uint8_t numBitsPerRes, rsvnDepth; + uint32_t durUsec; + uint32_t offsetUnitUs = schRmCb.commonInt >> (schRmCb.offsetDepth + depth); - /* b'11 becomes b'00010001, when depth is 2. */ - schRmCb.rmStatus = 0; - for (x = 0; x < (1 << schRmCb.offsetDepth); x++) + /* Check if the offsetDepth will be valid after the increase. */ + if (offsetUnitUs < SCH_RM_MIN_OFFSET_UNIT_US) { - if ((tmpStatus >> x) & 0x01) - { - schRmCb.rmStatus |= (0x01 << (x * (1 << depth))); - } + return FALSE; } + schRmCb.rmStatus = 0; schRmCb.offsetDepth += depth; /* Update database according to the new offsetDepth. */ + /* rmStatus b'11 becomes b'00010001, when depth is 2. */ for (handle = 0; handle < SCH_RM_MAX_RSVN; handle++) { if (schRmCb.rsvn[handle].commIntUsed) { + numBitsPerRes = 1; /* Number of bit offsets to be occupied by the reservation. */ + durUsec = schRmCb.rsvn[handle].durUsec; + WSF_ASSERT(durUsec < schRmCb.commonInt); + + if (schRmCb.commonInt == schRmCb.rsvn[handle].interUsec) + { + rsvnDepth = 0; + } + else + { + rsvnDepth = schRmIntCalculateDepth(schRmCb.commonInt, schRmCb.rsvn[handle].interUsec); + WSF_ASSERT(rsvnDepth > 0); + } + + while (durUsec >= offsetUnitUs) + { + numBitsPerRes++; + durUsec -= offsetUnitUs; + } + /* For example, with depth 2, bit1 will move into bit4. */ schRmCb.rsvn[handle].offsetBit *= (1 << depth); + + /* Re-construct rmStatus */ + for (y = 0; y < (1 << rsvnDepth); y++) + { + for (z = 0; z < numBitsPerRes; z++) + { + schRmCb.rmStatus |= (0x01 << ((0x01 << (schRmCb.offsetDepth - rsvnDepth)) * y + schRmCb.rsvn[handle].offsetBit + z)); + } + } } } + + return TRUE; } /*************************************************************************************************/ /*! * \brief Decrease reservation manager offset depth by one if necessary. - * - * \return None. */ /*************************************************************************************************/ static void schRmIntCheckDecOffsetDepth(void) @@ -434,14 +504,30 @@ static void schRmIntCheckDecOffsetDepth(void) /*************************************************************************************************/ static void schRmIntRemoveRmOffset(uint8_t handle) { - uint8_t x, depth; + uint8_t x, y, depth; + uint8_t numBitsPerRes = 1; /* Number of consecutive offset bits occupied by the reservation. */ + uint32_t durUsec; + uint32_t offsetUnitUs = schRmCb.commonInt >> schRmCb.offsetDepth; if (schRmCb.rsvn[handle].commIntUsed) { + WSF_ASSERT(schRmCb.rsvn[handle].durUsec < schRmCb.commonInt); + + /* Check how many continuous bit offsets were occupied by this reservation. */ + durUsec = schRmCb.rsvn[handle].durUsec; + while (durUsec >= offsetUnitUs) + { + numBitsPerRes++; + durUsec -= offsetUnitUs; + } + /* The interval of this handle must be equal to or smaller than the common interval. */ if (schRmCb.commonInt == schRmCb.rsvn[handle].interUsec) { - schRmCb.rmStatus &= ~(1 << schRmCb.rsvn[handle].offsetBit); + for (y = 0; y < numBitsPerRes; y++) + { + schRmCb.rmStatus &= ~(1 << (schRmCb.rsvn[handle].offsetBit + y)); + } } else { @@ -451,7 +537,10 @@ static void schRmIntRemoveRmOffset(uint8_t handle) { for (x = 0; x < (1 << depth); x++) { - schRmCb.rmStatus &= ~(1 << ((1 << (schRmCb.offsetDepth - depth)) * x + schRmCb.rsvn[handle].offsetBit)); + for (y = 0; y < numBitsPerRes; y++) + { + schRmCb.rmStatus &= ~(1 << ((1 << (schRmCb.offsetDepth - depth)) * x + schRmCb.rsvn[handle].offsetBit + y)); + } } } } @@ -468,9 +557,9 @@ static void schRmIntRemoveRmOffset(uint8_t handle) schRmCb.offsetDepth = 0; } - LL_TRACE_WARN2("schRmIntRemoveRmOffset, handle = %u, offsetDepth = %u", handle, schRmCb.offsetDepth); - LL_TRACE_WARN1(" rmStatus = 0x%x", schRmCb.rmStatus); - LL_TRACE_WARN1(" commonInt = %u", schRmCb.commonInt); + LL_TRACE_INFO2("schRmIntRemoveRmOffset, handle = %u, offsetDepth = %u", handle, schRmCb.offsetDepth); + LL_TRACE_INFO1(" rmStatus = 0x%x", schRmCb.rmStatus); + LL_TRACE_INFO1(" commonInt = %u", schRmCb.commonInt); } else { @@ -478,7 +567,7 @@ static void schRmIntRemoveRmOffset(uint8_t handle) { /* Uncommon handle by reservation manager. */ schRmCb.indexUncommon--; - LL_TRACE_WARN2("schRmIntRemoveRmOffset, deleted uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); + LL_TRACE_INFO2("schRmIntRemoveRmOffset, deleted uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); } } } @@ -488,8 +577,6 @@ static void schRmIntRemoveRmOffset(uint8_t handle) * \brief Increase common interval of reservation manager. * * \param depth Depth between current interval and new interval. - * - * \return None. */ /*************************************************************************************************/ static void schRmIntIncCommInterval(uint8_t depth) @@ -523,15 +610,17 @@ static void schRmIntIncCommInterval(uint8_t depth) /*! * \brief Handle Adding resource manager offset for the specified handle. * - * \param handle Client defined reservation handle. + * \param handle Client defined reservation handle. + * \param newInterUsec Interval of the reservation in microseconds. + * \param durUsec Duration of the reservation in microseconds. * * \return TRUE if update was successful, FALSE otherwise.. */ /*************************************************************************************************/ -static void schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec) +static bool_t schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec, uint32_t durUsec) { - schRmCb.rsvn[handle].handle = handle; - schRmCb.rsvn[handle].interUsec = newInterUsec; + bool_t status = TRUE; + uint8_t numAttempt = 0; /* Let's assume all connections are with common multiples. */ /* Will add function later to determine if 2 intervals are with common intervals. */ @@ -548,11 +637,23 @@ static void schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec) } else if (schRmCb.commonInt == newInterUsec) { - if (!schRmIntAddRmOffset(handle, 0)) + while (status == TRUE) { - /* Offset depth needs to be increased if RM status is full with the current depth. */ - schRmIntIncOffsetDepth(1); - (void)schRmIntAddRmOffset(handle, 0); + numAttempt++; + if (schRmIntAddRmOffset(handle, 0, newInterUsec, durUsec)) + { + break; + } + else if (numAttempt <= SCH_RM_ADD_MAX_ATTEMPTS) + { + /* Offset depth needs to be increased if RM status is full with the current depth. */ + status = schRmIntIncOffsetDepth(1); + } + else + { + /* Failed with maximum attempts. */ + status = FALSE; + } } } else if (schRmCb.commonInt < newInterUsec) /* new interval is multiple of commonInt. */ @@ -563,18 +664,30 @@ static void schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec) { schRmIntIncCommInterval(depth); - if (!schRmIntAddRmOffset(handle, 0)) + while (status == TRUE) { - /* Offset depth needs to be increased if RM status is full with the current depth. */ - schRmIntIncOffsetDepth(1); - (void)schRmIntAddRmOffset(handle, 0); + numAttempt++; + if (schRmIntAddRmOffset(handle, 0, newInterUsec, durUsec)) + { + break; + } + else if (numAttempt <= SCH_RM_ADD_MAX_ATTEMPTS) + { + /* Offset depth needs to be increased if RM status is full with the current depth. */ + status = schRmIntIncOffsetDepth(1); + } + else + { + /* Failed with maximum attempts. */ + status = FALSE; + } } } else { /* Uncommon handle by reservation manager. */ schRmCb.indexUncommon++; - LL_TRACE_WARN2("Adding uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); + LL_TRACE_INFO2("Adding uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); } } else if (schRmCb.commonInt > newInterUsec) @@ -586,23 +699,48 @@ static void schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec) /* First update offset depth so that offset unit would be same as new interval. */ if (schRmCb.offsetDepth < depth) { - schRmIntIncOffsetDepth(depth - schRmCb.offsetDepth); + status = schRmIntIncOffsetDepth(depth - schRmCb.offsetDepth); } - if (!schRmIntAddRmOffset(handle, depth)) + while (status == TRUE) { - /* Offset depth needs to be increased if RM status is full with the current depth. */ - schRmIntIncOffsetDepth(1); - (void)schRmIntAddRmOffset(handle, depth); + numAttempt++; + if (schRmIntAddRmOffset(handle, depth, newInterUsec, durUsec)) + { + break; + } + else if (numAttempt <= SCH_RM_ADD_MAX_ATTEMPTS) + { + /* Offset depth needs to be increased if RM status is full with the current depth. */ + status = schRmIntIncOffsetDepth(1); + } + else + { + /* Failed with maximum attempts. */ + status = FALSE; + } } } else { /* Uncommon handle by reservation manager. */ schRmCb.indexUncommon++; - LL_TRACE_WARN2("Adding uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); + LL_TRACE_INFO2("Adding uncommon index %u, Handle = %u", schRmCb.indexUncommon, handle); } } + + if (status == TRUE) + { + schRmCb.rsvn[handle].handle = handle; + schRmCb.rsvn[handle].interUsec = newInterUsec; + schRmCb.rsvn[handle].durUsec = durUsec; + } + else + { + LL_TRACE_WARN2("schRmIntHandleAddRmOffset, Add RM failed, Handle = %u, Interval = %u", handle, newInterUsec); + } + + return status; } /*************************************************************************************************/ @@ -612,8 +750,6 @@ static void schRmIntHandleAddRmOffset(uint8_t handle, uint32_t newInterUsec) * \param item List of numbers. * \param numItems Number of numbers in item[]. * Descending - * - * \return None. */ /*************************************************************************************************/ void schRmSortListDescending(uint32_t item[], uint8_t numItems) @@ -650,8 +786,6 @@ void schRmSortListDescending(uint32_t item[], uint8_t numItems) /*************************************************************************************************/ /*! * \brief Initialize the resource manager. - * - * \return None. */ /*************************************************************************************************/ void SchRmInit(void) @@ -659,18 +793,6 @@ void SchRmInit(void) memset(&schRmCb, 0, sizeof(schRmCb)); } -/*************************************************************************************************/ -/*! - * \brief Preferred periodicity. - * - * \return Preferred periodicity in microseconds. - */ -/*************************************************************************************************/ -uint32_t SchRmPreferredPeriodUsec(void) -{ - return SCH_RM_PREF_PER_USEC; -} - /*************************************************************************************************/ /*! * \brief Calculate the common periodicity. @@ -701,14 +823,16 @@ uint32_t SchRmCalcCommonPeriodicityUsec(uint32_t peerPerUsec) * \param pref Preference for selecting the interval. * \param minUsec Minimum interval in microseconds. * \param maxUsec Maximum interval in microseconds. - * \param durUsec Duration of the connection in microseconds. + * \param durUsec Duration of the reservation in microseconds. * \param pInterUsec Actual interval return value in microseconds. + * \param refTimeCb Get reference time callback function. * * \return TRUE if reservation available, FALSE otherwise. */ /*************************************************************************************************/ bool_t SchRmAdd(uint8_t handle, uint8_t pref, uint32_t minUsec, uint32_t maxUsec, uint32_t durUsec, uint32_t *pInterUsec, GetRefTimeCb_t refTimeCb) { + bool_t status = FALSE; uint32_t perfPerUsec = SCH_RM_PREF_PER_CONN_USEC; WSF_ASSERT(handle < SCH_RM_MAX_RSVN); @@ -732,17 +856,20 @@ bool_t SchRmAdd(uint8_t handle, uint8_t pref, uint32_t minUsec, uint32_t maxUsec /*** Commit reservation. ***/ - schRmCb.rsvnInterUsec[handle] = prefInterUsec; - schRmCb.numRsvn++; - if (pInterUsec) + status = schRmIntHandleAddRmOffset(handle, prefInterUsec, durUsec); + if (status == TRUE) { - *pInterUsec = prefInterUsec; - } + schRmCb.rsvn[handle].refTimeCb = refTimeCb; - schRmIntHandleAddRmOffset(handle, prefInterUsec); - schRmCb.rsvn[handle].refTimeCb = refTimeCb; + schRmCb.rsvnInterUsec[handle] = prefInterUsec; + schRmCb.numRsvn++; + if (pInterUsec) + { + *pInterUsec = prefInterUsec; + } + } - return TRUE; + return status; } /*************************************************************************************************/ @@ -783,7 +910,7 @@ bool_t SchRmStartUpdate(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint *pInterUsec = prefInterUsec; schRmIntRemoveRmOffset(handle); - schRmIntHandleAddRmOffset(handle, prefInterUsec); + (void)schRmIntHandleAddRmOffset(handle, prefInterUsec, durUsec); return TRUE; } @@ -793,8 +920,6 @@ bool_t SchRmStartUpdate(uint8_t handle, uint32_t minUsec, uint32_t maxUsec, uint * \brief Commit an update to a reservation. * * \param handle Client defined reservation handle. - * - * \return None. */ /*************************************************************************************************/ void SchRmCommitUpdate(uint8_t handle) @@ -807,8 +932,6 @@ void SchRmCommitUpdate(uint8_t handle) * \brief Remove an existing reservation. * * \param handle Client defined reservation handle. - * - * \return None. */ /*************************************************************************************************/ void SchRmRemove(uint8_t handle) @@ -822,30 +945,13 @@ void SchRmRemove(uint8_t handle) schRmIntRemoveRmOffset(handle); } -/*************************************************************************************************/ -/*! - * \brief Set the current reference point. - * - * \param handle Client defined reservation handle. - * - * \return None. - * - * The handle is the last completed reservation. Set the reference point to the next reservation - * represented by this handle. - */ -/*************************************************************************************************/ -void SchRmSetReference(uint8_t handle) -{ - /* No action required. */ -} - /*************************************************************************************************/ /*! * \brief Get the next available offset in microseconds. * * \param defOffsUsec Default offset in microseconds. * \param handle Reservation handle. - * \param refTime Reference time in BB ticks. + * \param refTime Reference time in microseconds. * * \return Offset in microseconds. */ @@ -860,8 +966,9 @@ uint32_t SchRmGetOffsetUsec(uint32_t defOffsUsec, uint8_t handle, uint32_t refTi if (schRmCb.numRsvn <= 1) { - /* No competing reservations. */ - return defOffsUsec; + /* We do not have reference anchor point yet for the 1st reservation. */ + /* First anchor point will be chosen to avoid conflict with TM links. */ + return SchTmGetFirstAnchor(refTime, defOffsUsec, schRmCb.rsvn[handle].interUsec, schRmCb.rsvn[handle].durUsec); } /* rmRefTime is the time for offset bit 0. */ @@ -879,17 +986,17 @@ uint32_t SchRmGetOffsetUsec(uint32_t defOffsUsec, uint8_t handle, uint32_t refTi offsUsec += schRmCb.rsvn[handle].interUsec; } - targetTime = rmRefTime + BB_US_TO_BB_TICKS(offsUsec); + targetTime = rmRefTime + offsUsec; - LL_TRACE_WARN2("SchRmGetOffsetUsec, handle = %u, refHandle = %u", handle, schRmCb.refHandle); - LL_TRACE_WARN1(" refTime = %u", refTime); - LL_TRACE_WARN1(" targetTime = %u", targetTime); + LL_TRACE_INFO2("SchRmGetOffsetUsec, handle = %u, refHandle = %u", handle, schRmCb.refHandle); + LL_TRACE_INFO1(" refTime = %u", refTime); + LL_TRACE_INFO1(" targetTime = %u", targetTime); } else { uint8_t offsetBit = 0; uint8_t numUncommon = schRmCb.indexUncommon; - uint32_t uncommonOffsetUs = SCH_RM_OFFSET_UNCOMMON; /* Offset in microseconds for uncommon handle */ + uint32_t uncommonOffsetUs = SCH_RM_OFFSET_UNCOMMON_US; /* Offset in microseconds for uncommon handle */ numUncommon--; while (numUncommon) @@ -900,38 +1007,38 @@ uint32_t SchRmGetOffsetUsec(uint32_t defOffsUsec, uint8_t handle, uint32_t refTi } /* Find the duration of BOD of the handle which occupies the offset bit. */ - for (uint8_t i = 0; i < SCH_RM_MAX_RSVN; i++) + for (unsigned int i = 0; i < SCH_RM_MAX_RSVN; i++) { if ((schRmCb.rsvn[i].offsetBit == offsetBit) && (schRmCb.rsvn[i].commIntUsed == TRUE)) { if (schRmCb.rsvn[i].refTimeCb != NULL) { (void)schRmCb.rsvn[i].refTimeCb(i, &uncommonOffsetUs); - uncommonOffsetUs += BbGetSchSetupDelayUs(); + uncommonOffsetUs += BbGetSchSetupDelayUs() + SCH_RM_MARGIN_UNCOMMON_US; } } } /* Place the uncommon handle away from each common ones to avoid conflicts. */ - targetTime = rmRefTime + BB_US_TO_BB_TICKS(offsetBit * offsetUnitUs) + BB_US_TO_BB_TICKS(uncommonOffsetUs); + targetTime = rmRefTime + (offsetBit * offsetUnitUs) + uncommonOffsetUs; - LL_TRACE_WARN2("SchRmGetOffsetUsec, uncommon handle = %u, refHandle = %u", handle, schRmCb.refHandle); - LL_TRACE_WARN1(" refTime = %u", refTime); - LL_TRACE_WARN1(" targetTime = %u", targetTime); + LL_TRACE_INFO2("SchRmGetOffsetUsec, uncommon handle = %u, refHandle = %u", handle, schRmCb.refHandle); + LL_TRACE_INFO1(" refTime = %u", rmRefTime); + LL_TRACE_INFO1(" targetTime = %u", targetTime); } /* Time to return has to be future from refTime. */ - while (targetTime - refTime >= SCH_RM_MAX_SPAN) + while (BbGetTargetTimeDelta(targetTime, refTime) == 0) { - targetTime += BB_US_TO_BB_TICKS(schRmCb.rsvn[handle].interUsec); + targetTime += schRmCb.rsvn[handle].interUsec; } /* 0 < targetTime <= interval */ - while (targetTime - refTime > BB_US_TO_BB_TICKS(schRmCb.rsvn[handle].interUsec)) + while (BbGetTargetTimeDelta(targetTime, refTime) > schRmCb.rsvn[handle].interUsec) { - targetTime -= BB_US_TO_BB_TICKS(schRmCb.rsvn[handle].interUsec); + targetTime -= schRmCb.rsvn[handle].interUsec; } - LL_TRACE_WARN1(" offsUsec = %u", (targetTime - refTime)); - return BB_TICKS_TO_US(targetTime - refTime); + LL_TRACE_INFO1(" offsUsec = %u", (targetTime - refTime)); + return BbGetTargetTimeDelta(targetTime, refTime); } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_tm.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_tm.c new file mode 100644 index 00000000000..20121f8351e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/ble/sch/sch_tm.c @@ -0,0 +1,352 @@ +/*************************************************************************************************/ +/*! + * \file + * + * \brief BLE topology manager implementation file. + * + * Copyright (c) 2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*************************************************************************************************/ + +#include "sch_int_tm.h" +#include "sch_int_rm.h" +#include "wsf_assert.h" +#include "wsf_math.h" +#include + +/************************************************************************************************** + Data Types +**************************************************************************************************/ + +/*! \brief Topology link node descriptor. */ +typedef struct +{ + uint32_t tBegin; /*!< Begin time of topology link node. */ + uint32_t tEnd; /*!< End time of topology link node. */ +} schTmNode_t; + +/*! \brief Topology link node control block. */ +typedef struct +{ + schTmNode_t tnode[SCH_TM_MAX_LINK + 1]; /*!< Information for each topology node. */ +} schTmNodeCb_t; + +/************************************************************************************************** + Global Variables +**************************************************************************************************/ + +/*! \brief Topology manager control block. */ +SchTmCb_t schTmCb; + +/*************************************************************************************************/ +/*! + * \brief Initialize the topology manager. + */ +/*************************************************************************************************/ +void SchTmInit(void) +{ + memset(&schTmCb, 0, sizeof(schTmCb)); +} + +/*************************************************************************************************/ +/*! + * \brief Add a new topology link. + * + * \param handle Client defined topology handle. + * \param interUsec Interval in microseconds. + * \param durUsec Duration of the topology link in microseconds. + * \param movable Movable. + * \param refTimeCb Callback function to get reference time. + */ +/*************************************************************************************************/ +void SchTmAdd(uint8_t handle, uint32_t interUsec, uint32_t durUsec, bool_t movable, GetTopRefTimeCb_t refTimeCb) +{ + WSF_ASSERT(handle < SCH_TM_MAX_LINK); + + schTmCb.tlink[handle].enabled = TRUE; + schTmCb.tlink[handle].movable = movable; + schTmCb.tlink[handle].interUsec = interUsec; + schTmCb.tlink[handle].durUsec = durUsec; + schTmCb.tlink[handle].refTimeCb = refTimeCb; + + LL_TRACE_INFO2("Topology Add, handle=%u, interval_ms=%u", handle, LL_MATH_DIV_10E3(interUsec)); + LL_TRACE_INFO1("Topology Add, durUsec=%u", durUsec); +} + +/*************************************************************************************************/ +/*! + * \brief Remove an existing topology link. + * + * \param handle Client defined topology handle. + */ +/*************************************************************************************************/ +void SchTmRemove(uint8_t handle) +{ + WSF_ASSERT(handle < SCH_TM_MAX_LINK); + + schTmCb.tlink[handle].enabled = FALSE; + LL_TRACE_INFO1("Topology Remove, handle=%u", handle); +} + +/*************************************************************************************************/ +/*! + * \brief Check if given timing parameters have conflict with any topology links. + * + * \param refBegin Reference time in microseconds. + * \param interUsec Interval in microseconds. + * \param durUsec Duration in microseconds. + * + * \return TRUE if conflict is found with any of topology links. + */ +/*************************************************************************************************/ +bool_t SchTmCheckConflict(uint32_t refBegin, uint32_t interUsec, uint32_t durUsec) +{ + uint32_t refEnd = refBegin + durUsec + BbGetSchSetupDelayUs(); /* End time of the link to be compared. */ + uint32_t linkBegin, linkEnd; /* Begin and end time of topology link. */ + uint8_t i; + + for (i = 0; i < SCH_TM_MAX_LINK; i++) + { + if ((schTmCb.tlink[i].enabled == TRUE) && schTmCb.tlink[i].refTimeCb) + { + /* First check if the links have common interval. */ + if (((interUsec > schTmCb.tlink[i].interUsec) && (schRmIntCalculateDepth(interUsec, schTmCb.tlink[i].interUsec) == 0)) || + ((interUsec < schTmCb.tlink[i].interUsec) && (schRmIntCalculateDepth(schTmCb.tlink[i].interUsec, interUsec) == 0))) + { + continue; + } + + linkBegin = schTmCb.tlink[i].refTimeCb(i); + + /* Start from the time when the TM link is in the past from the reference time. */ + while (SCH_TM_IS_IN_FUTURE(linkBegin, refBegin)) + { + linkBegin -= schTmCb.tlink[i].interUsec; + } + + linkEnd = linkBegin + schTmCb.tlink[i].durUsec + BbGetSchSetupDelayUs(); + + /* Now, check conflicts between TM link and the reference. */ + while (!SCH_TM_IS_IN_FUTURE(linkBegin, refEnd)) + { + /* Found conflict. */ + if (!SCH_TM_IS_IN_PAST(linkEnd, refBegin)) + { + LL_TRACE_WARN1("SchTmCheckConflict, ======>>> Found conflict with TM link %u ", i); + return TRUE; + } + + /* Use the smaller interval to check conflicts. */ + linkBegin += (interUsec < schTmCb.tlink[i].interUsec) ? interUsec : schTmCb.tlink[i].interUsec; + linkEnd = linkBegin + schTmCb.tlink[i].durUsec + BbGetSchSetupDelayUs(); + } + } + } + + return FALSE; +} + +/*************************************************************************************************/ +/*! + * \brief Find the best location to place the first anchor point. + * + * \param refTime Reference time in microseconds. + * \param defOffsUsec Default offset in microseconds. + * \param interUsec Interval in microseconds. + * \param durUsec Duration in microseconds. + * + * \return Anchor point offset from the reference time. + */ +/*************************************************************************************************/ +uint32_t SchTmGetFirstAnchor(uint32_t refTime, uint32_t defOffsUsec, uint32_t interUsec, uint32_t durUsec) +{ + schTmNodeCb_t schTmNodeCb; + uint8_t i, numNode, refLink, curLink, bestIndex; + uint32_t lastEnd, curBegin, rangeBegin, rangeEnd; + uint32_t nextBegin, nextEnd; /* Begin and end time of the next node to add. */ + uint32_t gap, biggestGap, commInterUsec; + bool_t done[SCH_TM_MAX_LINK]; + + numNode = 0; + commInterUsec = interUsec; + memset(done, FALSE, SCH_TM_MAX_LINK); + + /* Construct schTmNodeCb from schTmCb. */ + /* When there are 3 links(A,B,C), the order in schTmNodeCb will be A0 - B0 - C0 - A1.*/ + for (i = 0; i < SCH_TM_MAX_LINK; i++) + { + /* Find the first link which will be used as a reference time. */ + if ((schTmCb.tlink[i].enabled == TRUE) && schTmCb.tlink[i].refTimeCb) + { + /* Check if the links have common interval. */ + if (((interUsec > schTmCb.tlink[i].interUsec) && (schRmIntCalculateDepth(interUsec, schTmCb.tlink[i].interUsec) == 0)) || + ((interUsec < schTmCb.tlink[i].interUsec) && (schRmIntCalculateDepth(schTmCb.tlink[i].interUsec, interUsec) == 0))) + { + done[i] = TRUE; + } + else + { + /* Use smaller common interval. */ + commInterUsec = WSF_MIN(commInterUsec, schTmCb.tlink[i].interUsec); + + if (numNode == 0) + { + refLink = i; + schTmNodeCb.tnode[numNode].tBegin = schTmCb.tlink[i].refTimeCb(i); + schTmNodeCb.tnode[numNode].tEnd = schTmNodeCb.tnode[numNode].tBegin + schTmCb.tlink[i].durUsec; + + rangeBegin = schTmNodeCb.tnode[numNode].tBegin; + done[i] = TRUE; + numNode++; + } + } + } + else + { + done[i] = TRUE; + } + } + + if (numNode == 0) + { + /* Nothing to do. */ + return defOffsUsec; + } + + rangeEnd = rangeBegin + commInterUsec; + + /* Find next ones. */ + while (TRUE) + { + lastEnd = schTmNodeCb.tnode[numNode - 1].tEnd; + curLink = 0xFF; /* invalid */ + nextBegin = 0; /* invalid */ + + /* Find node which is closest from nextBegin. */ + for (i = 0; i < SCH_TM_MAX_LINK; i++) + { + if (done[i] == FALSE) + { + /* curBegin should be between rangeBegin and rangeEnd. */ + curBegin = schTmCb.tlink[i].refTimeCb(i); + while (SCH_TM_IS_IN_PAST(curBegin, rangeBegin)) + { + curBegin += commInterUsec; + } + + while (SCH_TM_IS_IN_FUTURE(curBegin, rangeEnd)) + { + curBegin -= commInterUsec; + } + + if (curLink == 0xFF) + { + curLink = i; + nextBegin = curBegin; + } + else + { + if (SCH_TM_IS_IN_PAST(curBegin, nextBegin)) + { + curLink = i; + nextBegin = curBegin; + } + } + } + } + + if (curLink != 0xFF) + { + done[curLink] = TRUE; + nextEnd = nextBegin + schTmCb.tlink[curLink].durUsec; + + /* Check if we can merge two nodes when they overlap. */ + if (SCH_TM_IS_IN_FUTURE(nextBegin, lastEnd)) + { + schTmNodeCb.tnode[numNode].tBegin = nextBegin; + schTmNodeCb.tnode[numNode].tEnd = nextBegin + schTmCb.tlink[curLink].durUsec; + numNode++; + } + else + { + /* Overlap. Merge nodes. */ + schTmNodeCb.tnode[numNode - 1].tEnd = SCH_TM_IS_IN_FUTURE(nextEnd, lastEnd) ? nextEnd : lastEnd; + } + } + else + { + /* Finished sorting. */ + break; + } + } + + /* Add A1(next instance of link A) at the end. */ + if (numNode > 0) + { + lastEnd = schTmNodeCb.tnode[numNode - 1].tEnd; + nextBegin = schTmNodeCb.tnode[0].tBegin + commInterUsec; + nextEnd = nextBegin + schTmCb.tlink[refLink].durUsec; + + /* Check if we can merge two nodes when they overlap. */ + if (SCH_TM_IS_IN_FUTURE(nextBegin, lastEnd)) + { + schTmNodeCb.tnode[numNode].tBegin = nextBegin; + schTmNodeCb.tnode[numNode].tEnd = nextBegin + schTmCb.tlink[refLink].durUsec; + numNode++; + } + else + { + /* Overlap. Merge nodes. */ + schTmNodeCb.tnode[numNode - 1].tEnd = SCH_TM_IS_IN_FUTURE(nextEnd, lastEnd) ? nextEnd : lastEnd; + } + } + + WSF_ASSERT(numNode >= 2); + + biggestGap = 0; + bestIndex = 0; + + /* Find biggest gap between nodes. */ + for (i = 0; i < (numNode - 1); i++) + { + gap = schTmNodeCb.tnode[i + 1].tBegin - schTmNodeCb.tnode[i].tEnd; + + if (gap > biggestGap) + { + biggestGap = gap; + bestIndex = i; + } + } + + uint32_t anchorTime = schTmNodeCb.tnode[bestIndex].tEnd + (biggestGap >> 1) - (durUsec >> 1); + + while (SCH_TM_IS_IN_PAST(anchorTime, refTime)) + { + anchorTime += commInterUsec; + } + + while (SCH_TM_IS_IN_FUTURE(anchorTime, (refTime + interUsec))) + { + anchorTime -= commInterUsec; + } + + LL_TRACE_INFO1("Topology SchTmGetFirstAnchor, refTime=%u", refTime); + LL_TRACE_INFO1("Topology SchTmGetFirstAnchor, anchorTime=%u", anchorTime); + + /* Return value should be 0 ~ defOffsecUsec. */ + return (anchorTime - refTime); +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_int.h index 6f9b65d96ea..f2433394c8b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_int.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_int.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal baseband interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2016-2018 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal baseband interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -48,6 +49,7 @@ typedef struct BbBodCback_t cancelOpCback; /*!< Cancel operation handler. */ BbProtCback_t startProtCback; /*!< Start protocol handler. */ BbProtCback_t stopProtCback; /*!< Stop protocol handler. */ + BbLowPowerCback_t lowPowerOpCback; /*!< Low power operation handler. */ uint32_t startCnt; /*!< Start counter. */ } prot[BB_PROT_NUM]; /*!< Protocol callbacks. */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_main.c index c7f1d7f7869..9c90edbab8d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/bb/bb_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Generic baseband driver implementation file. + * \file + * + * \brief Generic baseband driver implementation file. + * + * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -43,8 +44,6 @@ const BbRtCfg_t *pBbRtCfg = NULL; /*!< Runtime configuration. */ * * \param pCfg Pointer to runtime configuration parameters (data must be static). * - * \return None. - * * This function initializes the BB subsystem's runtime configuration. * * \note This routine must be called only once before any other initialization routine. @@ -59,6 +58,7 @@ void BbInitRunTimeCfg(const BbRtCfg_t *pCfg) WSF_ASSERT(pCfg->rfSetupDelayUs > 0); WSF_ASSERT(pCfg->maxScanPeriodMs > 0); WSF_ASSERT(pCfg->schSetupDelayUs > 0); + WSF_ASSERT(pCfg->BbTimerBoundaryUs > 0); pBbRtCfg = pCfg; } @@ -67,8 +67,6 @@ void BbInitRunTimeCfg(const BbRtCfg_t *pCfg) /*! * \brief Initialize the BB. * - * \return None. - * * Initialize baseband resources. */ /*************************************************************************************************/ @@ -87,8 +85,6 @@ void BbInit(void) * * \param eventCback Event callback. * - * \return None. - * * Register operation completion handler. */ /*************************************************************************************************/ @@ -102,8 +98,6 @@ void BbRegister(BbBodCompCback_t eventCback) * \brief Start BB processing of given protocol. * * \param protId Protocol ID. - * - * \return None. */ /*************************************************************************************************/ static void bbProtStart(uint8_t protId) @@ -125,8 +119,6 @@ static void bbProtStart(uint8_t protId) * * \param protId Protocol ID. * - * \return None. - * * Enable BB and start processing the list of BODs. This routine may be called several times, if * a protocol layers has several simultaneously-enabled operations. However, \ref BbStop() must * be called an equal number of time to disable the baseband. @@ -153,8 +145,6 @@ void BbStart(uint8_t protId) * \brief Stop BB processing of given protocol. * * \param protId Protocol ID. - * - * \return None. */ /*************************************************************************************************/ static void bbProtStop(uint8_t protId) @@ -203,8 +193,6 @@ void BbStop(uint8_t protId) * * \param pBod Pointer to the BOD to execute. * - * \return None. - * * Execute the protocol specific BOD handler. */ /*************************************************************************************************/ @@ -250,8 +238,6 @@ void BbExecuteBod(BbOpDesc_t *pBod) /*************************************************************************************************/ /*! * \brief Cancel current executing BOD. - * - * \return None. */ /*************************************************************************************************/ void BbCancelBod(void) @@ -286,8 +272,6 @@ BbOpDesc_t *BbGetCurrentBod(void) /*! * \brief Set termination flag of current executing BOD. * - * \return None. - * * \note This function is expected to be called during the execution context of the * current executing BOD, typically in the related ISRs. In the end, termination * flag will help to decide if BbTerminateBod() should be called. @@ -317,8 +301,6 @@ bool_t BbGetBodTerminateFlag(void) /*! * \brief Terminate a BOD immediately. * - * \return None. - * * \note This function is expected to be called during the execution context of the * current executing BOD, typically in the related ISRs. */ @@ -327,6 +309,13 @@ void BbTerminateBod(void) { WSF_ASSERT(bbCb.bodCompCback); + BbOpDesc_t * const pBod = bbCb.pOpInProgress; + if (pBod && + (bbCb.prot[pBod->protId].lowPowerOpCback != NULL)) + { + bbCb.prot[pBod->protId].lowPowerOpCback(); + } + bbCb.pOpInProgress = NULL; bbCb.termBod = TRUE; bbCb.bodCompCback(); @@ -346,6 +335,19 @@ uint16_t BbGetClockAccuracy(void) return pBbRtCfg->clkPpm; } +/*************************************************************************************************/ +/*! + * \brief Get BB timer boundary before wraparound. + * + * \return Time boundary in microseconds. + * + */ +/*************************************************************************************************/ +uint32_t BbGetBbTimerBoundaryUs(void) +{ + return pBbRtCfg->BbTimerBoundaryUs; +} + /*************************************************************************************************/ /*! * \brief Get scheduler setup delay. @@ -360,6 +362,96 @@ uint16_t BbGetSchSetupDelayUs(void) return pBbRtCfg->schSetupDelayUs; } +/*************************************************************************************************/ +/*! + * \brief Adjust new time tick with wraparound. + * + * \param dueUsec Time tick without wraparound in microseconds. + + * + * \return Time tick with wraparound. + * + * \note dueUsec can only be at most +/-(BbTimerBoundaryUs/2) out of range. + */ +/*************************************************************************************************/ +uint32_t BbAdjustTime(uint32_t dueUsec) +{ + /* If and only of dueUsec is outside the range of [0, BbTimerBoundaryUs], mapping adjustment is needed. */ + if (dueUsec > pBbRtCfg->BbTimerBoundaryUs) + { + /* dueUsec is in range [-(BbTimerBoundaryUs + 1)/2, 0). */ + if (dueUsec >= ~(pBbRtCfg->BbTimerBoundaryUs >> 1)) + { + dueUsec += (pBbRtCfg->BbTimerBoundaryUs + 1); + } + /* dueUsec is in range [(BbTimerBoundaryUs + 1), (BbTimerBoundaryUs + 1) + (BbTimerBoundaryUs + 1) / 2). */ + else if (dueUsec <= (pBbRtCfg->BbTimerBoundaryUs + 1 + (pBbRtCfg->BbTimerBoundaryUs >> 1))) + { + dueUsec -= (pBbRtCfg->BbTimerBoundaryUs + 1); + } + else + { + /* It should never happen here. */ + WSF_ASSERT(FALSE); + } + } + + /* If dueUsec is in range [0, BbTimerBoundaryUs], no need to adjust. */ + return dueUsec; +} + +/*************************************************************************************************/ +/*! + * \brief Get Delta between target and reference time. Only valid if target time is in the future. + * + * \param targetUsec Target time in microseconds. + * \param refUsec Reference time in microseconds. + * + * \return Positive number in microseconds if target time is in the future. + * Zero if target time is in the past or same compared with reference time. + * + * \note Caller has to make sure target time and reference time are within SCH_MAX_SPAN. + */ +/*************************************************************************************************/ +uint32_t BbGetTargetTimeDelta(uint32_t targetUsec, uint32_t refUsec) +{ + targetUsec = BbAdjustTime(targetUsec); + refUsec = BbAdjustTime(refUsec); + + uint32_t delta = 0; + + if (targetUsec > refUsec) + { + /* Always bigger number minus smaller number. */ + if ((targetUsec - refUsec) < ((pBbRtCfg->BbTimerBoundaryUs >> 1) + 1)) + { + /* Normal case. */ + delta = targetUsec - refUsec; + } + else + { + /* reference time must be wraparound and target time is in the past.*/ + delta = 0; + } + } + else + { + /* Always bigger number minus smaller number. */ + if ((refUsec - targetUsec) < ((pBbRtCfg->BbTimerBoundaryUs >> 1) + 1)) + { + /* target time is in the past. */ + delta = 0; + } + else + { + /* Target time must be wraparound. */ + delta = pBbRtCfg->BbTimerBoundaryUs - (refUsec - targetUsec) + 1; + } + } + + return delta; +} + /*************************************************************************************************/ /*! * \brief Returns the ID of the active protocol. @@ -381,12 +473,10 @@ uint8_t BbGetActiveProtocol(void) * \param cancelOpCback Cancel operation callback. * \param startProtCback Start protocol callback. * \param stopProtCback Stop protocol callback. - * - * \return None. */ /*************************************************************************************************/ -void BbRegisterProt(uint8_t protId, BbBodCback_t execOpCback, BbBodCback_t cancelOpCback, - BbProtCback_t startProtCback, BbProtCback_t stopProtCback) +void BbRegisterProt(PalBbProt_t protId, BbBodCback_t execOpCback, BbBodCback_t cancelOpCback, + BbProtCback_t startProtCback, BbProtCback_t stopProtCback) { WSF_ASSERT(protId < BB_PROT_NUM); WSF_ASSERT(startProtCback != NULL); @@ -397,3 +487,18 @@ void BbRegisterProt(uint8_t protId, BbBodCback_t execOpCback, BbBodCback_t cance bbCb.prot[protId].startProtCback = startProtCback; bbCb.prot[protId].stopProtCback = stopProtCback; } + +/*************************************************************************************************/ +/*! + * \brief Register protocol handlers for low power. + * + * \param protId Protocol ID. + * \param lowPowerOpCback Low power operation callback. + */ +/*************************************************************************************************/ +void BbRegisterProtLowPower(PalBbProt_t protId, BbLowPowerCback_t lowPowerOpCback) +{ + WSF_ASSERT(protId < BB_PROT_NUM); + WSF_ASSERT(lowPowerOpCback != NULL); + bbCb.prot[protId].lowPowerOpCback = lowPowerOpCback; +} diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c index c77fb5aac2b..391e9d69ac0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - /*************************************************************************************************/ /*! - * \file - * \brief Controller HCI transport module implementation file. + * \file + * + * \brief Controller HCI transport module implementation file. + * + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. + * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -34,8 +35,12 @@ #if (CHCI_TR_UART == 1) #include "pal_uart.h" #include "pal_sys.h" -#else -#include "fake_lhci_drv.h" +#endif + +#if (CHCI_TR_CUSTOM == 1) +/* Custom transport */ +extern void ChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen); +extern void ChciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData); #endif /************************************************************************************************** @@ -51,6 +56,9 @@ /*! \brief Maximum read header length. */ #define LHCI_MAX_RD_HDR_LEN (1 + 4) /* type + max header length */ +/*! \brief Maximum write buffer length allowed by UART DMA. */ +#define LHCI_MAX_DATA_LEN 4096 + /************************************************************************************************** Data Types **************************************************************************************************/ @@ -64,6 +72,9 @@ typedef struct uint8_t protPending; /*!< Protocol in progress. */ uint8_t nextAvailMask; /*!< Next available mask. */ + uint16_t maxAclLen; /*!< Maximum ACL data length. */ + uint16_t maxIsoSduLen; /*!< Maximum ISO data length. */ + uint32_t cmdCount; /*!< Counter of commands */ uint32_t evtCount; /*!< Counter of events */ @@ -77,17 +88,17 @@ typedef struct } protCbacks[CHCI_TR_PROT_NUM]; /*!< Callback array indexed by protocol ID. */ /* Read buffer state. */ - uint8_t rxPktState; /*!< Receive state. */ - uint8_t rdHdr[LHCI_MAX_RD_HDR_LEN]; /*!< Read header buffer. */ - uint16_t rdBufOffs; /*!< Write data buffer offset. */ - uint16_t rdBufLen; /*!< Write data buffer length. */ - uint8_t *pRdBuf; /*!< Read data buffer. */ + uint8_t rxPktState; /*!< Receive state. */ + uint8_t rdHdr[LHCI_MAX_RD_HDR_LEN]; /*!< Read header buffer. */ + uint16_t rdBufOffs; /*!< Write data buffer offset. */ + uint16_t rdBufLen; /*!< Write data buffer length. */ + uint8_t *pRdBuf; /*!< Read data buffer. */ /* Write buffer state. */ - uint16_t wrBufOffs; /*!< Write data buffer offset. */ - uint16_t wrBufLen; /*!< Write data buffer length. */ - uint8_t *pWrBuf; /*!< Write data buffer. */ - bool_t wrBufComp; /*!< Write buffer completed. */ + uint16_t wrBufOffs; /*!< Write data buffer offset. */ + uint16_t wrBufLen; /*!< Write data buffer length. */ + uint8_t *pWrBuf; /*!< Write data buffer. */ + bool_t wrBufComp; /*!< Write buffer completed. */ } chciTrCtrlBlk_t; /*! \brief Send handler. */ @@ -118,39 +129,37 @@ chciTrCtrlBlk_t chciTrCb; /*************************************************************************************************/ /*! - * \brief Signal a hardware error. - * - * \param code Error code. + * \brief Increment the command and event counters. * - * \return None. + * \param type Type of message. */ /*************************************************************************************************/ -static void chciTrHwError(uint8_t code) +static void chciTrIncrementCounters(uint8_t type) { - if (chciTrCb.sendHwErrorCback != NULL) + if (type == CHCI_TR_TYPE_CMD) { - chciTrCb.sendHwErrorCback(code); + chciTrCb.cmdCount++; + } + else if (type == CHCI_TR_TYPE_EVT) + { + chciTrCb.evtCount++; } } +#if (CHCI_TR_UART == 1) + /*************************************************************************************************/ /*! - * \brief Increment the command and event counters. - * - * \param type Type of message. + * \brief Signal a hardware error. * - * \return None. + * \param code Error code. */ /*************************************************************************************************/ -static void chciTrIncrementCounters(uint8_t type) +static void chciTrHwError(uint8_t code) { - if (type == CHCI_TR_TYPE_CMD) - { - chciTrCb.cmdCount++; - } - else if (type == CHCI_TR_TYPE_EVT) + if (chciTrCb.sendHwErrorCback != NULL) { - chciTrCb.evtCount++; + chciTrCb.sendHwErrorCback(code); } } @@ -160,8 +169,6 @@ static void chciTrIncrementCounters(uint8_t type) * * \param len Number of bytes to write. * \param pData Byte array to write. - * - * \return None. */ /*************************************************************************************************/ static void chciTrRead(uint16_t len, uint8_t *pData) @@ -175,8 +182,6 @@ static void chciTrRead(uint16_t len, uint8_t *pData) /*************************************************************************************************/ /*! * \brief Receive packet state machine. - * - * \return None. */ /*************************************************************************************************/ static void chciRxPacketSM(void) @@ -186,7 +191,7 @@ static void chciRxPacketSM(void) { chciTrCb.rxPktState = CHCI_RX_STATE_HEADER; /* Determine header length based on packet type. */ - switch(chciTrCb.rdHdr[0]) + switch (chciTrCb.rdHdr[0]) { case HCI_CMD_TYPE: chciTrRead(HCI_CMD_HDR_LEN, &chciTrCb.rdHdr[1]); @@ -213,6 +218,7 @@ static void chciRxPacketSM(void) { uint8_t hdrLen = 0; uint16_t dataLen = 0; + uint16_t allocLen = 0; /* Extract data length from header. */ switch (chciTrCb.rdHdr[0]) @@ -220,26 +226,50 @@ static void chciRxPacketSM(void) case HCI_CMD_TYPE: hdrLen = HCI_CMD_HDR_LEN; dataLen = (uint16_t)chciTrCb.rdHdr[3]; + allocLen = dataLen; break; case HCI_ACL_TYPE: hdrLen = HCI_ACL_HDR_LEN; BYTES_TO_UINT16(dataLen, &chciTrCb.rdHdr[3]); + if (dataLen > chciTrCb.maxAclLen) + { + chciTrHwError(CHCI_TR_CODE_INVALID_DATA_LEN); + chciTrCb.rxPktState = CHCI_RX_STATE_IDLE; + return; + } + /* Use data buffers located in the large pool. */ + allocLen = chciTrCb.maxAclLen + CHCI_BUF_TAILROOM; break; case HCI_ISO_TYPE: hdrLen = HCI_ISO_HDR_LEN; BYTES_TO_UINT16(dataLen, &chciTrCb.rdHdr[3]); + if (dataLen > (chciTrCb.maxIsoSduLen + HCI_ISO_DL_MAX_LEN)) + { + chciTrHwError(CHCI_TR_CODE_INVALID_DATA_LEN); + chciTrCb.rxPktState = CHCI_RX_STATE_IDLE; + return; + } + /* Use data buffers located in the large pool. */ + allocLen = HCI_ISO_DL_MAX_LEN + chciTrCb.maxIsoSduLen + CHCI_BUF_TAILROOM; break; case CHCI_15P4_CMD_TYPE: case CHCI_15P4_DATA_TYPE: hdrLen = CHCI_15P4_HDR_LEN; BYTES_TO_UINT16(dataLen, &chciTrCb.rdHdr[2]); + allocLen = dataLen; break; default: /* already validated in CHCI_RX_STATE_TYPE */ break; } - if ((chciTrCb.pRdBuf = (uint8_t *)WsfMsgAlloc(hdrLen + dataLen + CHCI_BUF_TAILROOM)) != NULL) + if (dataLen > LHCI_MAX_DATA_LEN) + { + /* Invalid byte received. */ + chciTrHwError(CHCI_TR_CODE_INVALID_DATA); + chciTrCb.rxPktState = CHCI_RX_STATE_IDLE; + } + else if ((chciTrCb.pRdBuf = (uint8_t *)WsfMsgAlloc(hdrLen + allocLen)) != NULL) { if (dataLen > 0) { @@ -294,20 +324,20 @@ static void chciRxPacketSM(void) switch (chciTrCb.rdHdr[0]) { - case HCI_CMD_TYPE: - chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_CMD, chciTrCb.pRdBuf); + case HCI_ISO_TYPE: + chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_ISO, chciTrCb.pRdBuf); break; case HCI_ACL_TYPE: - chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_DATA, chciTrCb.pRdBuf); + chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_ACL, chciTrCb.pRdBuf); break; - case HCI_ISO_TYPE: - chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_ISO, chciTrCb.pRdBuf); + case HCI_CMD_TYPE: + chciTrRecv(CHCI_TR_PROT_BLE, CHCI_TR_TYPE_CMD, chciTrCb.pRdBuf); break; case CHCI_15P4_CMD_TYPE: chciTrRecv(CHCI_TR_PROT_15P4, CHCI_TR_TYPE_CMD, chciTrCb.pRdBuf); break; case CHCI_15P4_DATA_TYPE: - chciTrRecv(CHCI_TR_PROT_15P4, CHCI_TR_TYPE_DATA, chciTrCb.pRdBuf); + chciTrRecv(CHCI_TR_PROT_15P4, CHCI_TR_TYPE_ACL, chciTrCb.pRdBuf); break; default: break; @@ -331,8 +361,6 @@ static void chciRxPacketSM(void) /*************************************************************************************************/ /*! * \brief Tx complete callback. - * - * \return None. */ /*************************************************************************************************/ static void chciTxComplete(void) @@ -353,6 +381,8 @@ static void chciTxComplete(void) } } +#endif /* (CHCI_TR_UART == 1) */ + /*************************************************************************************************/ /*! * \brief Write data the driver. @@ -362,8 +392,6 @@ static void chciTxComplete(void) * \param len Number of bytes to write. * \param pData Byte array to write. * - * \return None. - * * \note The type parameter allows the driver layer to prepend the data with a header on the * same write transaction. */ @@ -383,7 +411,7 @@ static void chciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData { *(pData - 1) = HCI_EVT_TYPE; } - else if (type == CHCI_TR_TYPE_DATA) + else if (type == CHCI_TR_TYPE_ACL) { *(pData - 1) = HCI_ACL_TYPE; } @@ -399,10 +427,10 @@ static void chciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData /* Initiate Tx operation. */ PalUartWriteData(PAL_UART_ID_CHCI, chciTrCb.pWrBuf, chciTrCb.wrBufOffs); PalSysSetBusy(); -#else - FakeChciTrWrite(prot, type, len, pData); - chciTrCb.wrBufComp = TRUE; - ChciTrService(); +#endif + +#if (CHCI_TR_CUSTOM == 1) + ChciTrWrite(prot, type, len, pData); #endif } @@ -410,13 +438,11 @@ static void chciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData /*! * \brief Signal the completion of a message write. * - * \return None. - * * This routine is used for asynchronous write operations. When the driver has completed the * use of the write buffer, this routine is called to free the buffer and release flow control. */ /*************************************************************************************************/ -static void chciTrSendComplete(void) +void chciTrSendComplete(void) { uint8_t *pBuf = chciTrCb.pDataPending; uint8_t type = chciTrCb.typePending; @@ -436,8 +462,6 @@ static void chciTrSendComplete(void) * * \param pCmdCount Pointer to uint32_t to hold command count. * \param pEvtCount Pointer to uint32_t to hold event count. - * - * \return None. */ /*************************************************************************************************/ void ChciTrGetCmdEvtCounts(uint32_t *pCmdCount, uint32_t *pEvtCount) @@ -449,8 +473,6 @@ void ChciTrGetCmdEvtCounts(uint32_t *pCmdCount, uint32_t *pEvtCount) /*************************************************************************************************/ /*! * \brief Reset the HCI command and event counts to zero. - * - * \return None. */ /*************************************************************************************************/ void ChciTrResetCmdEvtCounts(void) @@ -464,28 +486,33 @@ void ChciTrResetCmdEvtCounts(void) * \brief Initialize the transport handler. * * \param handlerId Handler ID. - * - * \return None. + * \param maxAclLen Maximum ACL data length. + * \param maxIsoSduLen Maximum ISO data length. */ /*************************************************************************************************/ -void ChciTrHandlerInit(wsfHandlerId_t handlerId) +void ChciTrHandlerInit(wsfHandlerId_t handlerId, uint16_t maxAclLen, uint16_t maxIsoSduLen) { memset(&chciTrCb, 0, sizeof(chciTrCb)); chciTrCb.handlerId = handlerId; + chciTrCb.maxAclLen = maxAclLen; + chciTrCb.maxIsoSduLen = maxIsoSduLen; #if (CHCI_TR_UART == 1) PalUartConfig_t cfg; cfg.baud = UART_BAUD; - cfg.hwFlow = UART_DEFAULT_CONFIG_HWFC; + cfg.hwFlow = UART_HWFC; cfg.rdCback = chciRxPacketSM; cfg.wrCback = chciTxComplete; PalUartInit(PAL_UART_ID_CHCI, &cfg); + + /* Start receiver. */ + chciRxPacketSM(); +#elif (CHCI_TR_CUSTOM == 1) + ChciTrInit(maxAclLen, maxIsoSduLen); #else (void)chciRxPacketSM; (void)chciTxComplete; #endif - /* Start receiver. */ - chciRxPacketSM(); } /*************************************************************************************************/ @@ -494,8 +521,6 @@ void ChciTrHandlerInit(wsfHandlerId_t handlerId) * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void ChciTrHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) @@ -536,8 +561,6 @@ void ChciTrHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) * \param recvCback Message received callback. * \param sendCompleteCback Message send complete callback. * \param serviceCback Service callback. - * - * \return None. */ /*************************************************************************************************/ void ChciTrSetCbacks(uint8_t prot, ChciTrRecvCback_t recvCback, ChciTrSendCompleteCback_t sendCompleteCback, @@ -556,8 +579,6 @@ void ChciTrSetCbacks(uint8_t prot, ChciTrRecvCback_t recvCback, ChciTrSendComple * \brief Set send hardware error callback. * * \param sendHwErrorCback Send hardware error callback. - * - * \return None. */ /*************************************************************************************************/ void ChciTrSetSendHwErrorCback(ChciTrSendHwErrorCback_t sendHwErrorCback) @@ -570,8 +591,6 @@ void ChciTrSetSendHwErrorCback(ChciTrSendHwErrorCback_t sendHwErrorCback) * \brief Flag protocol for needing service. * * \param prot Protocol. - * - * \return None. */ /*************************************************************************************************/ void ChciTrNeedsService(uint8_t prot) @@ -589,8 +608,6 @@ void ChciTrNeedsService(uint8_t prot) * \param prot Protocol. * \param type Message type. * \param pBuf Message. - * - * \return None. */ /*************************************************************************************************/ void chciTrRecv(uint8_t prot, uint8_t type, uint8_t *pBuf) @@ -620,15 +637,15 @@ void chciTrRecv(uint8_t prot, uint8_t type, uint8_t *pBuf) /*************************************************************************************************/ bool_t ChciTrService(void) { +#if (CHCI_TR_UART == 1) if (chciTrCb.wrBufComp) { chciTrCb.wrBufComp = FALSE; chciTrSendComplete(); - #if (CHCI_TR_UART == 1) PalSysSetIdle(); - #endif return TRUE; } +#endif return FALSE; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_int.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_int.h index 20d1ca969b8..b687c8d0f04 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_int.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_int.h @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Internal multi-protocol scheduler interface file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 ARM Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Internal multi-protocol scheduler interface file. + * Copyright (c) 2019 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -36,8 +37,8 @@ extern "C" { Macros **************************************************************************************************/ -/*! \brief Maximum span of scheduler elements. */ -#define SCH_MAX_SPAN 0x80000000 +/*! \brief Maximum span of scheduler elements. Half of the boundary time. */ +#define SCH_MAX_SPAN ((BbGetBbTimerBoundaryUs() >> 1) + 1) /*! \brief Typical time needed for loading BOD. */ #define SCH_LOAD_DELAY_US 300 @@ -47,11 +48,11 @@ extern "C" { **************************************************************************************************/ /*! \brief Scheduler states. */ -enum +typedef enum { SCH_STATE_IDLE, /*!< Scheduler idle. */ SCH_STATE_EXEC /*!< Scheduler executing BOD. */ -}; +} schState_t; /************************************************************************************************** Data Types @@ -60,12 +61,17 @@ enum /*! \brief Scheduler control block. */ typedef struct { - bool_t state; /*!< Current scheduler state. */ - uint8_t eventSetFlagCount; /*!< Scheduler event set count. */ - wsfHandlerId_t handlerId; /*!< System event handler ID. */ + schState_t state:8; /*!< Current scheduler state. */ + uint8_t eventSetFlagCount; /*!< Scheduler event set count. */ + wsfHandlerId_t handlerId; /*!< System event handler ID. */ - BbOpDesc_t *pHead; /*!< Head element of scheduled list of BOD. */ - BbOpDesc_t *pTail; /*!< Tail element of scheduled list of BOD. */ + BbOpDesc_t *pHead; /*!< Head element of scheduled list of BOD. */ + BbOpDesc_t *pTail; /*!< Tail element of scheduled list of BOD. */ + + uint16_t schHandlerWatermarkUsec; /*!< Statistics: Handler duration watermark in microseconds. */ + uint16_t delayLoadWatermarkCount; /*!< Statistics: Delay loading watermark count. */ + uint16_t delayLoadCount; /*!< Statistics: Delay loading count. */ + uint32_t delayLoadTotalCount; /*!< Statistics: Delay loading total count. */ } SchCtrlBlk_t; /************************************************************************************************** @@ -96,17 +102,9 @@ void schRemoveHead(void); /*************************************************************************************************/ static inline bool_t schDueTimeInFuture(BbOpDesc_t *pBod) { - bool_t result = FALSE; - - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - const uint32_t delta = pBod->due - curTime; + const uint32_t curTime = PalBbGetCurrentTime(); - if (delta < SCH_MAX_SPAN) /* due time has not passed */ - { - result = TRUE; - } - - return result; + return (BbGetTargetTimeDelta(pBod->dueUsec, curTime) > 0); } @@ -123,17 +121,17 @@ static inline uint32_t schGetTimeToExecBod(BbOpDesc_t *pBod) { uint32_t result = 0; - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - const uint32_t delta = pBod->due - curTime; + const uint32_t curTime = PalBbGetCurrentTime(); + + result = BbGetTargetTimeDelta(pBod->dueUsec, curTime); - if ((delta >= BB_US_TO_BB_TICKS(SCH_LOAD_DELAY_US)) && /* sufficient time to cancel */ - (delta < SCH_MAX_SPAN)) /* due time has not passed */ + if (result >= SCH_LOAD_DELAY_US) { - result = BB_TICKS_TO_US(delta - BB_US_TO_BB_TICKS(SCH_LOAD_DELAY_US)); + result -= SCH_LOAD_DELAY_US; } else { - result = 0; + result = 0; } return result; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_list.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_list.c index 1acb01a1bb5..0b53e3741a8 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_list.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_list.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Operation list maintenance implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Operation list maintenance implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -33,25 +34,25 @@ **************************************************************************************************/ /*! \brief Total BOD time including setup delay. */ -#define SCH_TOTAL_DUR(p) (p->minDurUsec + BbGetSchSetupDelayUs()) +#define SCH_TOTAL_DUR(p) (p->minDurUsec + BbGetSchSetupDelayUs()) /*! \brief Time immediately after the given BOD. */ -#define SCH_END_TIME(p) (p->due + BB_US_TO_BB_TICKS(SCH_TOTAL_DUR(p))) +#define SCH_END_TIME(p) (p->dueUsec + SCH_TOTAL_DUR(p)) /*! \brief Is BOD[a] due time before BOD[b] due time (rt = reference time). */ -#define SCH_IS_DUE_BEFORE(a, b, rt) ((((a)->due) - (rt)) < (((b)->due) - (rt))) +#define SCH_IS_DUE_BEFORE(a, b) (BbGetTargetTimeDelta(((b)->dueUsec), ((a)->dueUsec)) > 0) /*! \brief Is BOD[a] completion time before BOD[b] due time (rt = reference time). */ -#define SCH_IS_DONE_BEFORE(a, b, rt) ((SCH_END_TIME(a) - (rt)) <= (((b)->due) - (rt))) +#define SCH_IS_DONE_BEFORE(a, b) (BbGetTargetTimeDelta(SCH_END_TIME(a), ((b)->dueUsec)) == 0) /*! \brief Is BOD[a] due time after BOD[b] completion time. */ -#define SCH_IS_DUE_AFTER(a, b, rt) SCH_IS_DONE_BEFORE(b, a, rt) +#define SCH_IS_DUE_AFTER(a, b) (BbGetTargetTimeDelta(SCH_END_TIME(b), ((a)->dueUsec)) == 0) /*! \brief Minimum time in microseconds to start scheduler timer. */ -#define SCH_MIN_TIMER_USEC 5 +#define SCH_MIN_TIMER_USEC 200 /*! \brief Margin in microseconds to cancel a BOD. */ -#define SCH_CANCEL_MARGIN_USEC 15 +#define SCH_CANCEL_MARGIN_USEC 15 #ifndef SCH_TRACE_ENABLE /*! \brief Enable scheduler trace. */ @@ -59,10 +60,10 @@ #endif #if SCH_TRACE_ENABLE -#define SCH_TRACE_INFO0(msg) WSF_TRACE0("SCH", "INFO", msg) -#define SCH_TRACE_INFO1(msg, var1) WSF_TRACE1("SCH", "INFO", msg, var1) -#define SCH_TRACE_WARN0(msg) WSF_TRACE0("SCH", "WARN", msg) -#define SCH_TRACE_WARN1(msg, var1) WSF_TRACE1("SCH", "WARN", msg, var1) +#define SCH_TRACE_INFO0(msg) WSF_TRACE0("SCH", "INFO", msg) +#define SCH_TRACE_INFO1(msg, var1) WSF_TRACE1("SCH", "INFO", msg, var1) +#define SCH_TRACE_WARN0(msg) WSF_TRACE0("SCH", "WARN", msg) +#define SCH_TRACE_WARN1(msg, var1) WSF_TRACE1("SCH", "WARN", msg, var1) #else /*! \brief Information trace with 0 parameters. */ #define SCH_TRACE_INFO0(msg) @@ -74,10 +75,10 @@ #define SCH_TRACE_WARN1(msg, var1) #endif /*! \brief Maximum allowed number of deleted BOD due to conflicts. */ -#define SCH_MAX_DELETE_BOD 8 +#define SCH_MAX_DELETE_BOD 8 #ifndef SCH_CHECK_LIST_INTEGRITY /*! \brief Check list requirements upon insertions and removals. */ -#define SCH_CHECK_LIST_INTEGRITY FALSE +#define SCH_CHECK_LIST_INTEGRITY FALSE #endif #if (SCH_CHECK_LIST_INTEGRITY) @@ -86,8 +87,6 @@ * \brief Ensure BOD is not already inserted in the list. * * \param pBod Target BOD. - * - * \return None. */ /*************************************************************************************************/ static inline void SchCheckIsNotInserted(BbOpDesc_t *pBod) @@ -141,11 +140,10 @@ static inline bool_t SchEnoughTimeToCancel(BbOpDesc_t *pBod) { bool_t result = FALSE; - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - const uint32_t delta = pBod->due - curTime; + const uint32_t curTime = PalBbGetCurrentTime(); + const uint32_t delta = BbGetTargetTimeDelta(pBod->dueUsec, curTime); - if ((delta >= BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs())) && /* sufficient time to cancel */ - (delta < SCH_MAX_SPAN)) /* due time has not passed */ + if (delta >= BbGetSchSetupDelayUs()) { result = TRUE; } @@ -153,27 +151,6 @@ static inline bool_t SchEnoughTimeToCancel(BbOpDesc_t *pBod) return result; } -/*************************************************************************************************/ -/*! - * \brief Get start reference time. - * - * \return Start reference time. - * - * Returns the earliest time as a time base for calculations. - */ -/*************************************************************************************************/ -static inline uint32_t SchGetStartRefTime(void) -{ - if (schCb.pHead) - { - return schCb.pHead->due - SCH_MAX_SPAN; - } - else - { - return PalBbGetCurrentTime(USE_RTC_BB_CLK); - } -} - /*************************************************************************************************/ /*! * \brief Check and return the status of whether it is ok to cancel the head BOD. @@ -210,8 +187,6 @@ static inline bool_t schCheckCancelHead(void) * \brief Insert item into an empty list. * * \param pItem Item to insert. - * - * \return None. */ /*************************************************************************************************/ static inline void schInsertToEmptyList(BbOpDesc_t *pItem) @@ -227,7 +202,7 @@ static inline void schInsertToEmptyList(BbOpDesc_t *pItem) pItem->pNext = NULL; SCH_TRACE_INFO1("++| schInsertToEmptyList |++ pBod=0x%08x", (uint32_t)pItem); - SCH_TRACE_INFO1("++| |++ .due=%u", pItem->due); + SCH_TRACE_INFO1("++| |++ .dueUsec=%u", pItem->dueUsec); SCH_TRACE_INFO1("++| |++ .minDurUsec=%u", pItem->minDurUsec); SCH_TRACE_INFO1("++| |++ .maxDurUsec=%u", pItem->maxDurUsec); } @@ -238,8 +213,6 @@ static inline void schInsertToEmptyList(BbOpDesc_t *pItem) * * \param pItem Item to insert. * \param pTgt Target position. - * - * \return None. */ /*************************************************************************************************/ static inline void schInsertBefore(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) @@ -261,7 +234,7 @@ static inline void schInsertBefore(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) } SCH_TRACE_INFO1("++| schInsertBefore |++ pBod=0x%08x", (uint32_t)pItem); - SCH_TRACE_INFO1("++| |++ .due=%u", pItem->due); + SCH_TRACE_INFO1("++| |++ .dueUsec=%u", pItem->dueUsec); SCH_TRACE_INFO1("++| |++ .minDurUsec=%u", pItem->minDurUsec); SCH_TRACE_INFO1("++| |++ .maxDurUsec=%u", pItem->maxDurUsec); } @@ -272,8 +245,6 @@ static inline void schInsertBefore(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) * * \param pItem Item to insert. * \param pTgt Target position. - * - * \return None. */ /*************************************************************************************************/ static inline void schInsertAfter(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) @@ -295,7 +266,7 @@ static inline void schInsertAfter(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) } SCH_TRACE_INFO1("++| schInsertAfter |++ pBod=0x%08x", (uint32_t)pItem); - SCH_TRACE_INFO1("++| |++ .due=%u", pItem->due); + SCH_TRACE_INFO1("++| |++ .dueUsec=%u", pItem->dueUsec); SCH_TRACE_INFO1("++| |++ .minDurUsec=%u", pItem->minDurUsec); SCH_TRACE_INFO1("++| |++ .maxDurUsec=%u", pItem->maxDurUsec); } @@ -303,8 +274,6 @@ static inline void schInsertAfter(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) /*************************************************************************************************/ /*! * \brief Remove head item from BOD list. - * - * \return None. */ /*************************************************************************************************/ void schRemoveHead(void) @@ -329,8 +298,6 @@ void schRemoveHead(void) * \brief Remove non-head item from BOD list. * * \param pBod Element to remove. - * - * \return None. */ /*************************************************************************************************/ static void schRemoveMiddle(BbOpDesc_t *pBod) @@ -501,8 +468,6 @@ static bool_t SchResolveConflict(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) int numDeletedBod = 0; BbOpDesc_t *pDeleted[SCH_MAX_DELETE_BOD]; - const uint32_t startRef = SchGetStartRefTime(); - WSF_ASSERT(pTgt); WSF_ASSERT(pItem); @@ -517,7 +482,7 @@ static bool_t SchResolveConflict(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) pDeleted[numDeletedBod++] = pCur; if ((pCur->pNext == NULL) || /* pCur is the tail. */ - (SCH_IS_DONE_BEFORE(pItem, pCur->pNext, startRef))) /* Only conflict with pCur. */ + (SCH_IS_DONE_BEFORE(pItem, pCur->pNext))) /* Only conflict with pCur. */ { /* Remove only 1 conflicting BOD. */ result = schRemoveForConflict(pCur); @@ -584,7 +549,7 @@ static bool_t SchResolveConflict(BbOpDesc_t *pItem, BbOpDesc_t *pTgt) static bool_t SchIsConflictResolvable(BbOpDesc_t *pItem, BbOpDesc_t *pTgt, BbConflictAct_t conflictCback) { bool_t result; - const uint32_t startRef = SchGetStartRefTime(); + BbOpDesc_t *pCur = pTgt; WSF_ASSERT(pTgt) @@ -593,7 +558,7 @@ static bool_t SchIsConflictResolvable(BbOpDesc_t *pItem, BbOpDesc_t *pTgt, BbCon while (TRUE) { if ((pCur->pNext == NULL) || /* pCur is the tail. */ - (SCH_IS_DONE_BEFORE(pItem, pCur->pNext, startRef))) /* Only conflict with pCur. */ + (SCH_IS_DONE_BEFORE(pItem, pCur->pNext))) /* Only conflict with pCur. */ { /* Only 1 conflicting BOD. */ result = SchIsBodResolvable(pItem, pCur, conflictCback); @@ -619,8 +584,6 @@ static bool_t SchIsConflictResolvable(BbOpDesc_t *pItem, BbOpDesc_t *pTgt, BbCon * \brief Try to load or add scheduler timer for inserted item if possible. * * \param pBod Inserted BOD. - * - * \return None. */ /*************************************************************************************************/ static inline void SchInsertTryLoadBod(BbOpDesc_t *pBod) @@ -656,7 +619,7 @@ static inline void SchInsertTryLoadBod(BbOpDesc_t *pBod) else if (pBod == schCb.pHead->pNext && schCb.state == SCH_STATE_EXEC) { /* At this moment, head BOD should be in the past. */ - WSF_ASSERT(schGetTimeToExecBod(schCb.pHead) == 0); + WSF_ASSERT(schGetTimeToExecBod(schCb.pHead) < SCH_MIN_TIMER_USEC); if (execTimeUsec >= SCH_MIN_TIMER_USEC) { @@ -681,8 +644,6 @@ static inline void SchInsertTryLoadBod(BbOpDesc_t *pBod) * * \param pBod Element to insert. * - * \return None. - * * Insert this BOD in the active BOD list where its duration can be accommodated. */ /*************************************************************************************************/ @@ -692,15 +653,13 @@ void SchInsertNextAvailable(BbOpDesc_t *pBod) SchCheckIsNotInserted(pBod); #endif - const uint32_t startRef = SchGetStartRefTime(); - - pBod->due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()); + pBod->dueUsec = PalBbGetCurrentTime() + BbGetSchSetupDelayUs(); if (schCb.pHead == NULL) { schInsertToEmptyList(pBod); } - else if (SCH_IS_DONE_BEFORE(pBod, schCb.pHead, startRef) && + else if (SCH_IS_DONE_BEFORE(pBod, schCb.pHead) && schCheckCancelHead()) { /* Insert at head */ @@ -716,13 +675,13 @@ void SchInsertNextAvailable(BbOpDesc_t *pBod) WSF_ASSERT(pBod != pCur); /* Only update due time when pCur ends in the future. */ - if (SCH_END_TIME(pCur) > pBod->due) + if (!SCH_IS_DONE_BEFORE(pCur, pBod)) { - pBod->due = SCH_END_TIME(pCur); + pBod->dueUsec = SCH_END_TIME(pCur); } if ((pCur->pNext == NULL) || /* insert at tail */ - SCH_IS_DONE_BEFORE(pBod, pCur->pNext, startRef)) + SCH_IS_DONE_BEFORE(pBod, pCur->pNext)) { schInsertAfter(pBod, pCur); break; @@ -755,8 +714,6 @@ bool_t SchInsertAtDueTime(BbOpDesc_t *pBod, BbConflictAct_t conflictCback) SchCheckIsNotInserted(pBod); #endif - const uint32_t startRef = SchGetStartRefTime(); - if (!schDueTimeInFuture(pBod)) { return FALSE; @@ -777,8 +734,7 @@ bool_t SchInsertAtDueTime(BbOpDesc_t *pBod, BbConflictAct_t conflictCback) while (TRUE) { WSF_ASSERT(pBod != pCur); - - if (SCH_IS_DONE_BEFORE(pBod, pCur, startRef)) /* BOD is due and done before pCur(no overlap), try to insert before. */ + if (SCH_IS_DONE_BEFORE(pBod, pCur)) /* BOD is due and done before pCur(no overlap), try to insert before. */ { if (pCur == schCb.pHead) { @@ -789,7 +745,7 @@ bool_t SchInsertAtDueTime(BbOpDesc_t *pBod, BbConflictAct_t conflictCback) result = TRUE; break; } - else if (!SCH_IS_DONE_BEFORE(pCur, pBod, startRef)) /* pCur has overlap with pBod, check priority and resolve BOD. */ + else if (!SCH_IS_DONE_BEFORE(pCur, pBod)) /* pCur has overlap with pBod, check priority and resolve BOD. */ { if ((result = SchIsConflictResolvable(pBod, pCur, conflictCback)) == TRUE) { @@ -798,7 +754,7 @@ bool_t SchInsertAtDueTime(BbOpDesc_t *pBod, BbConflictAct_t conflictCback) } break; } - else if (pCur->pNext == NULL) /* BOD is due after pCur and pCur is tail, insert after. */ + else if (pCur->pNext == NULL) /* BOD is due after pCur and pCur is tail, insert after. */ { schInsertAfter(pBod, pCur); result = TRUE; @@ -842,77 +798,82 @@ bool_t SchInsertEarlyAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) bool_t result = FALSE; - const uint32_t startRef = SchGetStartRefTime(); - const uint32_t dueOrigin = pBod->due; + const uint32_t dueOrigin = pBod->dueUsec; /* Try inserting at minimum interval. */ - pBod->due += min; + pBod->dueUsec += min; - if ((max == SCH_MAX_SPAN) && !schDueTimeInFuture(pBod)) - { - /* With SCH_MAX_SPAN, this function will insert the BOD regardless of the current due. */ - pBod->due = PalBbGetCurrentTime(USE_RTC_BB_CLK) + BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs()); - } - - if (schDueTimeInFuture(pBod)) + if (!schDueTimeInFuture(pBod)) { - if (schCb.pHead == NULL) + if (max != SCH_MAX_SPAN) { - schInsertToEmptyList(pBod); - result = TRUE; + /* Reset due time origin. */ + pBod->dueUsec = dueOrigin; + return FALSE; } - else if (SCH_IS_DUE_BEFORE (pBod, schCb.pHead, startRef) && - SCH_IS_DONE_BEFORE(pBod, schCb.pHead, startRef) && - schCheckCancelHead()) - { - /* Insert at head */ - WSF_ASSERT(pBod != schCb.pHead); - schInsertBefore(pBod, schCb.pHead); - result = TRUE; - } - else if (SCH_IS_DONE_BEFORE(schCb.pTail, pBod, startRef)) + else { - /* Insert at tail */ - WSF_ASSERT(pBod != schCb.pTail); - schInsertAfter(pBod, schCb.pTail); - result = TRUE; + /* With SCH_MAX_SPAN, this function will insert the BOD regardless of the current due. */ + pBod->dueUsec = PalBbGetCurrentTime() + BbGetSchSetupDelayUs(); } - else + } + + if (schCb.pHead == NULL) + { + schInsertToEmptyList(pBod); + result = TRUE; + } + else if (SCH_IS_DUE_BEFORE (pBod, schCb.pHead) && + SCH_IS_DONE_BEFORE(pBod, schCb.pHead) && + schCheckCancelHead()) + { + /* Insert at head */ + WSF_ASSERT(pBod != schCb.pHead); + schInsertBefore(pBod, schCb.pHead); + result = TRUE; + } + else if (SCH_IS_DONE_BEFORE(schCb.pTail, pBod)) + { + /* Insert at tail */ + WSF_ASSERT(pBod != schCb.pTail); + schInsertAfter(pBod, schCb.pTail); + result = TRUE; + } + else + { + BbOpDesc_t *pCur = schCb.pHead; + + while (pCur) { - BbOpDesc_t *pCur = schCb.pHead; + WSF_ASSERT(pBod != pCur); - while (pCur) + /* Only update due time when pCur ends in the future. */ + if (!SCH_IS_DONE_BEFORE(pCur, pBod)) { - WSF_ASSERT(pBod != pCur); + pBod->dueUsec = SCH_END_TIME(pCur); + } + uint32_t nextAvailInter = pBod->dueUsec - dueOrigin; - /* Only update due time when pCur ends in the future. */ - if (SCH_END_TIME(pCur) > pBod->due) + if ((nextAvailInter >= min) && + (nextAvailInter <= max)) + { + if (pCur->pNext == NULL) { - pBod->due = SCH_END_TIME(pCur); + /* Insert at tail */ + schInsertAfter(pBod, pCur); + result = TRUE; + break; } - uint32_t nextAvailInter = pBod->due - dueOrigin; - - if ((nextAvailInter >= min) && - (nextAvailInter <= max)) + else if (SCH_IS_DONE_BEFORE(pBod, pCur->pNext)) { - if (pCur->pNext == NULL) - { - /* Insert at tail */ - schInsertAfter(pBod, pCur); - result = TRUE; - break; - } - else if (SCH_IS_DONE_BEFORE(pBod, pCur->pNext, startRef)) - { - /* Insert middle. */ - schInsertBefore(pBod, pCur->pNext); - result = TRUE; - break; - } + /* Insert middle. */ + schInsertBefore(pBod, pCur->pNext); + result = TRUE; + break; } - - pCur = pCur->pNext; } + + pCur = pCur->pNext; } } @@ -924,7 +885,7 @@ bool_t SchInsertEarlyAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) if (!result) { /* Reset due time origin. */ - pBod->due = dueOrigin; + pBod->dueUsec = dueOrigin; } return result; @@ -954,11 +915,10 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) SchCheckIsNotInserted(pBod); #endif - const uint32_t startRef = SchGetStartRefTime(); - const uint32_t dueOrigin = pBod->due; + const uint32_t dueOrigin = pBod->dueUsec; /* Try inserting at maximum interval. */ - pBod->due = dueOrigin + max; + pBod->dueUsec = dueOrigin + max; if (schCb.pTail == NULL) { @@ -968,7 +928,7 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) result = TRUE; } } - else if (SCH_IS_DUE_AFTER(pBod, schCb.pTail, startRef)) + else if (SCH_IS_DUE_AFTER(pBod, schCb.pTail)) { if (schDueTimeInFuture(pBod)) { @@ -986,19 +946,16 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) { WSF_ASSERT(pBod != pCur); + /* The current BOD is the head BOD, check to see if there is time to schedule it before. */ if (pCur->pPrev == NULL) { - pBod->due = pCur->due - BB_US_TO_BB_TICKS(SCH_TOTAL_DUR(pBod)); + uint32_t nextAvailInter = BbGetTargetTimeDelta((pCur->dueUsec - SCH_TOTAL_DUR(pBod)), dueOrigin); + uint32_t targetOffset = WSF_MIN(max, nextAvailInter); + pBod->dueUsec = dueOrigin + targetOffset; - if (!schDueTimeInFuture(pBod)) - { - break; - } - - uint32_t nextAvailInter = pBod->due - dueOrigin; - - if ((nextAvailInter >= min) && - (nextAvailInter <= max) && + if ((targetOffset >= min) && + SCH_IS_DUE_BEFORE(pBod, pCur) && + schDueTimeInFuture(pBod) && schCheckCancelHead()) { /* Insert at head. */ @@ -1007,20 +964,21 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) break; } } + /* The current BOD is a intermediate BOD, check to see if we can insert in-between BODs. */ else { - pBod->due = SCH_END_TIME(pCur->pPrev); + pBod->dueUsec = SCH_END_TIME(pCur->pPrev); if (!schDueTimeInFuture(pBod)) { break; } - uint32_t nextAvailInter = pBod->due - dueOrigin; + uint32_t nextAvailInter = BbGetTargetTimeDelta(pBod->dueUsec, dueOrigin); if ((nextAvailInter >= min) && (nextAvailInter <= max) && - SCH_IS_DONE_BEFORE(pBod, pCur, startRef)) + SCH_IS_DONE_BEFORE(pBod, pCur)) { /* Insert middle. */ schInsertBefore(pBod, pCur); @@ -1041,7 +999,7 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) if (!result) { /* Reset due time origin. */ - pBod->due = dueOrigin; + pBod->dueUsec = dueOrigin; } return result; @@ -1053,7 +1011,7 @@ bool_t SchInsertLateAsPossible(BbOpDesc_t *pBod, uint32_t min, uint32_t max) * * \param pBod Element to remove. * - * \return Return TRUE if removed successfully, FALSE if item not in the list. + * \return Return TRUE if removed successfully, FALSE if item not in the list or there is not enough time to cancel. * * Remove item from list. */ @@ -1064,7 +1022,7 @@ bool_t SchRemove(BbOpDesc_t *pBod) if (!SchCheckIsInserted(pBod)) { - LL_TRACE_WARN0("No such BOD to remove."); + LL_TRACE_WARN0("No such BOD to remove"); return FALSE; } @@ -1147,7 +1105,7 @@ bool_t SchRemove(BbOpDesc_t *pBod) pBod->abortCback(pBod); } SCH_TRACE_INFO1("--| SchRemove |-- pBod=0x%08x", (uint32_t)pBod); - SCH_TRACE_INFO1("--| |-- .due=%u", pBod->due); + SCH_TRACE_INFO1("--| |-- .dueUsec=%u", pBod->dueUsec); } return result; @@ -1159,8 +1117,6 @@ bool_t SchRemove(BbOpDesc_t *pBod) * * \param pBod Element to reload. * - * \return None. - * * Only if the head operation, cancel the operation and re-start it. */ /*************************************************************************************************/ @@ -1169,6 +1125,7 @@ void SchReload(BbOpDesc_t *pBod) if ((schCb.pHead == pBod) && schCheckCancelHead()) { + PalTimerStop(); SchInsertTryLoadBod(pBod); } @@ -1190,12 +1147,10 @@ bool_t SchIsBodCancellable(BbOpDesc_t *pBod) WSF_ASSERT(pBod); bool_t result = FALSE; - const uint32_t curTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); - const uint32_t delta = pBod->due - curTime; + const uint32_t curTime = PalBbGetCurrentTime(); + const uint32_t delta = BbGetTargetTimeDelta(pBod->dueUsec, curTime); - /* Checking if bod can be cancelled by the client. */ - if ((delta >= (uint32_t)(BB_US_TO_BB_TICKS(BbGetSchSetupDelayUs() + SCH_CANCEL_MARGIN_USEC))) && /* sufficient time to cancel */ - (delta < SCH_MAX_SPAN)) /* due time has not passed */ + if (delta >= (uint32_t)(BbGetSchSetupDelayUs() + SCH_CANCEL_MARGIN_USEC)) { result = TRUE; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_main.c index 343c0bb5c2c..a29178a9572 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/sch/sch_main.c @@ -1,23 +1,24 @@ -/* Copyright (c) 2019 Arm Limited - * SPDX-License-Identifier: Apache-2.0 +/*************************************************************************************************/ +/*! + * \file * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * \brief Operation list maintenance implementation file. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************************************/ -/*! - * \file - * \brief Operation list maintenance implementation file. + * Copyright (c) 2019-2020 Packetcraft, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ /*************************************************************************************************/ @@ -47,14 +48,9 @@ enum /*! \brief Scheduler control block. */ SchCtrlBlk_t schCb; -/*! \brief Handler duration watermark in microseconds. */ -static uint16_t schHandlerWatermarkUsec = 0; - /*************************************************************************************************/ /*! * \brief BOD completion handler. - * - * \return None. */ /*************************************************************************************************/ static void schBodCompHandler(void) @@ -66,8 +62,6 @@ static void schBodCompHandler(void) /*************************************************************************************************/ /*! * \brief BOD abortion handler. - * - * \return None. */ /*************************************************************************************************/ static void schBodAbortHandler(void) @@ -79,8 +73,6 @@ static void schBodAbortHandler(void) /*************************************************************************************************/ /*! * \brief BOD curtail handler. - * - * \return None. */ /*************************************************************************************************/ static void schBodCurtailHandler(void) @@ -92,8 +84,6 @@ static void schBodCurtailHandler(void) /*************************************************************************************************/ /*! * \brief BOD load handler. - * - * \return None. */ /*************************************************************************************************/ static void schBodLoadHandler(void) @@ -105,46 +95,57 @@ static void schBodLoadHandler(void) WSF_ASSERT(pNextBod); /* Delay loading after event flag is cleared. */ WsfSetEvent(schCb.handlerId, SCH_EVENT_BOD_LOAD); + schCb.delayLoadCount++; + schCb.delayLoadTotalCount++; + if (schCb.delayLoadCount > schCb.delayLoadWatermarkCount) + { + schCb.delayLoadWatermarkCount = schCb.delayLoadCount; + } + return; } - else + + /* Try load head if scheduler is idle. */ + if (schCb.state == SCH_STATE_IDLE) { - /* Try load head if scheduler is idle. */ - if (schCb.state == SCH_STATE_IDLE) + if (!schTryLoadHead()) { - if (!schTryLoadHead()) - { - /* Head load failed. */ - schBodAbortHandler(); - } - /* Move to next BOD. */ - pNextBod = pNextBod->pNext; + /* Head load failed. */ + schBodAbortHandler(); } + /* Move to next BOD. */ + pNextBod = pNextBod->pNext; + } #if SCH_TIMER_REQUIRED == TRUE - /* If head is executed, check cur tail operation is needed or not. */ - else - { - /* Head BOD and next BOD must exist. */ - WSF_ASSERT(schCb.pHead); - WSF_ASSERT(schCb.pHead->pNext); - pNextBod = pNextBod->pNext; + /* If head is executed, check cur tail operation is needed or not. */ + else + { + /* Head BOD and next BOD must exist. */ + WSF_ASSERT(schCb.pHead); + WSF_ASSERT(schCb.pHead->pNext); + pNextBod = pNextBod->pNext; - /* Skip curtail load if next BOD has same or lower priority than current BOD. */ - if ((pNextBod->reschPolicy) >= (schCb.pHead->reschPolicy)) + /* Skip curtail load if next BOD has same or lower priority than current BOD. */ + if ((pNextBod->reschPolicy) >= (schCb.pHead->reschPolicy)) + { + /* Delay loading until idle state. */ + WsfSetEvent(schCb.handlerId, SCH_EVENT_BOD_LOAD); + schCb.delayLoadCount++; + schCb.delayLoadTotalCount++; + if (schCb.delayLoadCount > schCb.delayLoadWatermarkCount) { - /* Delay loading until idle state. */ - WsfSetEvent(schCb.handlerId, SCH_EVENT_BOD_LOAD); - return; + schCb.delayLoadWatermarkCount = schCb.delayLoadCount; } + return; + } - if (!schTryCurTailLoadNext()) - { - /* Curtail load failed. */ - schBodAbortHandler(); - } - /* Move to the next next BOD. */ - pNextBod = pNextBod->pNext; + if (!schTryCurTailLoadNext()) + { + /* Curtail load failed. */ + schBodAbortHandler(); } + /* Move to the next next BOD. */ + pNextBod = pNextBod->pNext; } /* If pNextBod exists, it should start scheduler timer. */ @@ -161,19 +162,17 @@ static void schBodLoadHandler(void) else { /* If this happens, it means there's something wrong with the scheduler list. */ - LL_TRACE_WARN0(" Next BOD overlaps with current BOD. "); + LL_TRACE_WARN0("Next BOD overlaps with current BOD"); /* Send scheduler load event. */ SchLoadHandler(); } -#endif } +#endif } /*************************************************************************************************/ /*! * \brief Scheduler load handler. - * - * \return None. */ /*************************************************************************************************/ void SchLoadHandler(void) @@ -184,8 +183,6 @@ void SchLoadHandler(void) /*************************************************************************************************/ /*! * \brief Initialize the scheduler subsystem. - * - * \return None. */ /*************************************************************************************************/ void SchInit(void) @@ -201,8 +198,6 @@ void SchInit(void) * * \param handlerId WSF handler ID. * - * \return None. - * * \note This initialization to used to enable task-based scheduler completions. For * ISR-based scheduler completions, do not call this routine. Instead install an * ISR which calls SchHandler() on BOD completions. @@ -220,8 +215,6 @@ void SchHandlerInit(wsfHandlerId_t handlerId) /*************************************************************************************************/ /*! * \brief Reset the scheduler subsystem. - * - * \return None. */ /*************************************************************************************************/ void SchReset(void) @@ -229,6 +222,9 @@ void SchReset(void) schCb.state = SCH_STATE_IDLE; schCb.pHead = NULL; schCb.pTail = NULL; + schCb.schHandlerWatermarkUsec = 0; + schCb.delayLoadWatermarkCount = 0; + schCb.delayLoadTotalCount = 0; } /*************************************************************************************************/ @@ -237,8 +233,6 @@ void SchReset(void) * * \param event WSF event. * \param pMsg WSF message. - * - * \return None. */ /*************************************************************************************************/ void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) @@ -247,81 +241,86 @@ void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) (void)pMsg; /* Assume scheduler clock started. */ - uint32_t startTime = PalTimerGetCurrentTime(); - - BbOpDesc_t *pBod = schCb.pHead; - - if (!pBod) - { - schCb.state = SCH_STATE_IDLE; - return; - } + uint32_t startTime = PalBbGetCurrentTime(); - if (event & SCH_EVENT_BOD_COMPLETE) + while (event != 0) { - WSF_ASSERT(schCb.state == SCH_STATE_EXEC); - WSF_ASSERT(schCb.eventSetFlagCount); + BbOpDesc_t *pBod = schCb.pHead; - /*** Complete current BOD ***/ - - schCb.state = SCH_STATE_IDLE; - schRemoveHead(); - if (pBod->endCback) + if (!pBod) { - pBod->endCback(pBod); + schCb.eventSetFlagCount = 0; + schCb.state = SCH_STATE_IDLE; + return; } - schCb.eventSetFlagCount--; + + if (event & SCH_EVENT_BOD_COMPLETE) + { + WSF_ASSERT(schCb.state == SCH_STATE_EXEC); + WSF_ASSERT(schCb.eventSetFlagCount); + + /*** Complete current BOD ***/ + + schCb.state = SCH_STATE_IDLE; + schRemoveHead(); + if (pBod->endCback) + { + pBod->endCback(pBod); + } + schCb.eventSetFlagCount--; #if SCH_TIMER_REQUIRED == FALSE - schBodLoadHandler(); + schBodLoadHandler(); #endif - } + event &= ~SCH_EVENT_BOD_COMPLETE; + } - if (event & SCH_EVENT_BOD_ABORT) - { - WSF_ASSERT(schCb.state == SCH_STATE_IDLE); - WSF_ASSERT(schCb.eventSetFlagCount); + else if (event & SCH_EVENT_BOD_ABORT) + { + WSF_ASSERT(schCb.state == SCH_STATE_IDLE); + WSF_ASSERT(schCb.eventSetFlagCount); - /*** Abort current BOD ***/ + /*** Abort current BOD ***/ - schRemoveHead(); - if (pBod->abortCback) - { - pBod->abortCback(pBod); - } - schCb.eventSetFlagCount--; + schRemoveHead(); + if (pBod->abortCback) + { + pBod->abortCback(pBod); + } + schCb.eventSetFlagCount--; #if SCH_TIMER_REQUIRED == FALSE - schBodLoadHandler(); + schBodLoadHandler(); #endif - } - - if (event & SCH_EVENT_BOD_CURTAIL) - { - WSF_ASSERT(schCb.state == SCH_STATE_EXEC); - WSF_ASSERT(schCb.eventSetFlagCount); + event &= ~SCH_EVENT_BOD_ABORT; + } - /*** Complete previous BOD ***/ - schRemoveHead(); - if (pBod->endCback) + else if (event & SCH_EVENT_BOD_CURTAIL) { - pBod->endCback(pBod); + WSF_ASSERT(schCb.eventSetFlagCount); + + /*** Complete previous BOD ***/ + schRemoveHead(); + if (pBod->endCback) + { + pBod->endCback(pBod); + } + schCb.eventSetFlagCount--; + event &= ~SCH_EVENT_BOD_CURTAIL; } - schCb.eventSetFlagCount--; - } - if (event & SCH_EVENT_BOD_LOAD) - { - schBodLoadHandler(); + else if (event & SCH_EVENT_BOD_LOAD) + { + schBodLoadHandler(); + event &= ~SCH_EVENT_BOD_LOAD; + } } - uint32_t curTick = PalTimerGetCurrentTime(); - /* Consider both count-up or counter-down timer type. */ - uint32_t durTick = (curTick- startTime < 0x80000000) ? (curTick - startTime) : (startTime - curTick); - uint16_t durUsec = PAL_TIMER_TICKS_TO_US(durTick); - if (schHandlerWatermarkUsec < durUsec) + uint32_t endTime = PalBbGetCurrentTime(); + uint32_t durUsec = BbGetTargetTimeDelta(endTime, startTime); + if (schCb.schHandlerWatermarkUsec < durUsec) { - schHandlerWatermarkUsec = durUsec; + schCb.schHandlerWatermarkUsec = durUsec; } } @@ -329,17 +328,20 @@ void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) /*! * \brief Load BOD if not already started. * + * \param pBod BOD description. + * * \return TRUE if loaded, FALSE otherwise. */ /*************************************************************************************************/ static bool_t schLoadBod(BbOpDesc_t *pBod) { - bool_t loaded = FALSE; + bool_t loaded = FALSE; if (schDueTimeInFuture(pBod)) { /* Setup BB services. */ BbExecuteBod(pBod); + schCb.delayLoadCount = 0; if (!BbGetBodTerminateFlag()) { @@ -361,7 +363,7 @@ static bool_t schLoadBod(BbOpDesc_t *pBod) else { /* This might occur due to the delay of conflict resolution. */ - LL_TRACE_WARN1("!!! Head element in the past, pBod=0x%08x", pBod); + LL_TRACE_ERR1("!!! Head element in the past, pBod=0x%08x", pBod); } return loaded; @@ -445,5 +447,29 @@ bool_t schTryLoadHead(void) /*************************************************************************************************/ uint16_t SchStatsGetHandlerWatermarkUsec(void) { - return schHandlerWatermarkUsec; + return schCb.schHandlerWatermarkUsec; +} + +/*************************************************************************************************/ +/*! + * \brief Get the scheduler handler watermark level. + * + * \return Watermark level in microseconds. + */ +/*************************************************************************************************/ +uint16_t SchStatsGetDelayLoadWatermarkCount(void) +{ + return schCb.delayLoadWatermarkCount; +} + +/*************************************************************************************************/ +/*! + * \brief Get the scheduler handler watermark level. + * + * \return Watermark level in microseconds. + */ +/*************************************************************************************************/ +uint32_t SchStatsGetDelayLoadTotalCount(void) +{ + return schCb.delayLoadTotalCount; } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/arduino_primo.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/arduino_primo.h index 07fe47950c4..2e462c17d70 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/arduino_primo.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/arduino_primo.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.c index b438f823874..4c7fe5d25d2 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.c @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA * * All rights reserved. * @@ -43,7 +43,6 @@ #endif #include #include -#include "nrf_assert.h" #if LEDS_NUMBER > 0 static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.h index 1ab0629c04c..35421d23adc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/boards.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * @@ -65,6 +65,8 @@ #include "pca10040.h" #elif defined(BOARD_PCA10056) #include "pca10056.h" +#elif defined(BOARD_PCA10100) + #include "pca10100.h" #elif defined(BOARD_PCA20020) #include "pca20020.h" #elif defined(BOARD_PCA10059) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/nrf6310.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/nrf6310.h index c4488228ec4..bd529458736 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/nrf6310.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/nrf6310.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2012 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10000.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10000.h index 3c33494673a..01fe58ba2cc 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10000.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10000.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2012 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10001.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10001.h index 8121516d0e6..9c7f228d6a7 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10001.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10001.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2012 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2012 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10003.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10003.h index 724cb0c0ca8..3562fd80f8a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10003.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10003.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10028.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10028.h index 946f158fdca..bd365db6c48 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10028.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10028.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10031.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10031.h index 538dedc4b6f..b8c6d6976f0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10031.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10031.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10036.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10036.h index 560a68c16a3..6aaddc5eca2 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10036.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10036.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10040.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10040.h index 2fa0fbe89d4..597ff69c6ef 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10040.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10040.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10056.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10056.h index 00ecc916892..8689dc00cd6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10056.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10056.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10059.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10059.h index 50fd2b2e09e..711edd428b1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10059.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10059.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10100.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10100.h new file mode 100644 index 00000000000..c44fb1bfc6e --- /dev/null +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca10100.h @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2019, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef PCA10100_H +#define PCA10100_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_gpio.h" + +// LEDs definitions for PCA10056 +#define LEDS_NUMBER 4 + +#define LED_1 NRF_GPIO_PIN_MAP(0,13) +#define LED_2 NRF_GPIO_PIN_MAP(0,14) +#define LED_3 NRF_GPIO_PIN_MAP(0,15) +#define LED_4 NRF_GPIO_PIN_MAP(0,16) +#define LED_START LED_1 +#define LED_STOP LED_4 + +#define LEDS_ACTIVE_STATE 0 + +#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 } + +#define LEDS_INV_MASK LEDS_MASK + +#define BSP_LED_0 13 +#define BSP_LED_1 14 +#define BSP_LED_2 15 +#define BSP_LED_3 16 + +#define BUTTONS_NUMBER 4 + +#define BUTTON_1 11 +#define BUTTON_2 12 +#define BUTTON_3 24 +#define BUTTON_4 25 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +#define BUTTONS_ACTIVE_STATE 0 + +#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 } + +#define BSP_BUTTON_0 BUTTON_1 +#define BSP_BUTTON_1 BUTTON_2 +#define BSP_BUTTON_2 BUTTON_3 +#define BSP_BUTTON_3 BUTTON_4 + +#define RX_PIN_NUMBER 8 +#define TX_PIN_NUMBER 6 +#define CTS_PIN_NUMBER 7 +#define RTS_PIN_NUMBER 5 +#define HWFC true + +// serialization APPLICATION board - temp. setup for running serialized MEMU tests +#define SER_APP_RX_PIN NRF_GPIO_PIN_MAP(1,13) // UART RX pin number. +#define SER_APP_TX_PIN NRF_GPIO_PIN_MAP(1,14) // UART TX pin number. +#define SER_APP_CTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Clear To Send pin number. +#define SER_APP_RTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Request To Send pin number. + +#define SER_APP_SPIM0_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI clock GPIO pin number. +#define SER_APP_SPIM0_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI Master Out Slave In GPIO pin number +#define SER_APP_SPIM0_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI Master In Slave Out GPIO pin number +#define SER_APP_SPIM0_SS_PIN NRF_GPIO_PIN_MAP(1,13) // SPI Slave Select GPIO pin number +#define SER_APP_SPIM0_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number +#define SER_APP_SPIM0_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number + +// serialization CONNECTIVITY board +#define SER_CON_RX_PIN NRF_GPIO_PIN_MAP(1,14) // UART RX pin number. +#define SER_CON_TX_PIN NRF_GPIO_PIN_MAP(1,13) // UART TX pin number. +#define SER_CON_CTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Clear To Send pin number. Not used if HWFC is set to false. +#define SER_CON_RTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Request To Send pin number. Not used if HWFC is set to false. + + +#define SER_CON_SPIS_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI SCK signal. +#define SER_CON_SPIS_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI MOSI signal. +#define SER_CON_SPIS_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI MISO signal. +#define SER_CON_SPIS_CSN_PIN NRF_GPIO_PIN_MAP(1,13) // SPI CSN signal. +#define SER_CON_SPIS_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number. +#define SER_CON_SPIS_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number. + +#define SER_CONN_CHIP_RESET_PIN NRF_GPIO_PIN_MAP(1,1) // Pin used to reset connectivity chip + +// Arduino board mappings +#define ARDUINO_SCL_PIN 27 // SCL signal pin +#define ARDUINO_SDA_PIN 26 // SDA signal pin +#define ARDUINO_AREF_PIN 2 // Aref pin + +#define ARDUINO_13_PIN NRF_GPIO_PIN_MAP(1, 23) // Digital pin 13 +#define ARDUINO_12_PIN NRF_GPIO_PIN_MAP(1, 22) // Digital pin 12 +#define ARDUINO_11_PIN NRF_GPIO_PIN_MAP(1, 21) // Digital pin 11 +#define ARDUINO_10_PIN NRF_GPIO_PIN_MAP(1, 20) // Digital pin 10 +#define ARDUINO_9_PIN NRF_GPIO_PIN_MAP(1, 19) // Digital pin 9 +#define ARDUINO_8_PIN NRF_GPIO_PIN_MAP(1, 17) // Digital pin 8 + +#define ARDUINO_7_PIN NRF_GPIO_PIN_MAP(1, 8) // Digital pin 7 +#define ARDUINO_6_PIN NRF_GPIO_PIN_MAP(1, 7) // Digital pin 6 +#define ARDUINO_5_PIN NRF_GPIO_PIN_MAP(1, 6) // Digital pin 5 +#define ARDUINO_4_PIN NRF_GPIO_PIN_MAP(1, 5) // Digital pin 4 +#define ARDUINO_3_PIN NRF_GPIO_PIN_MAP(1, 4) // Digital pin 3 +#define ARDUINO_2_PIN NRF_GPIO_PIN_MAP(1, 3) // Digital pin 2 +#define ARDUINO_1_PIN NRF_GPIO_PIN_MAP(1, 2) // Digital pin 1 +#define ARDUINO_0_PIN NRF_GPIO_PIN_MAP(1, 1) // Digital pin 0 + +#define ARDUINO_A0_PIN 3 // Analog channel 0 +#define ARDUINO_A1_PIN 4 // Analog channel 1 +#define ARDUINO_A2_PIN 28 // Analog channel 2 +#define ARDUINO_A3_PIN 29 // Analog channel 3 +#define ARDUINO_A4_PIN 30 // Analog channel 4 +#define ARDUINO_A5_PIN 31 // Analog channel 5 + + +#ifdef __cplusplus +} +#endif + +#endif // PCA10100_H diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20006.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20006.h index 3cedfc9ea8f..e8e3d68dc2b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20006.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20006.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20020.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20020.h index e253f4a150f..4d3a9065032 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20020.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/pca20020.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2017 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/wt51822.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/wt51822.h index eb0552b0a07..53cfbecffa6 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/wt51822.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/nordic-bsp/components/boards/wt51822.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014 - 2018, Nordic Semiconductor ASA + * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA * * All rights reserved. * diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c index ea351a6e43c..6ae4c45193a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c @@ -471,7 +471,7 @@ void uECC_set_rng(uECC_RNG_Function rng_function) { g_rng_function = rng_function; } -#if defined __GNUC__ && !defined(__ARMCC_VERSION) /* Only support GCC inline asm for now */ +#ifdef __GNUC__ /* Only support GCC inline asm for now */ #if (uECC_ASM && (uECC_PLATFORM == uECC_avr)) #include "asm_avr.inc" #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.c index abb8b20e0a2..41324c3985b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.c @@ -168,7 +168,7 @@ void uECC_set_rng_ll(uECC_RNG_Function rng_function) { g_rng_function = rng_function; } -#if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) && defined(__GNUC__) /* Only support GCC inline asm for now */ +#ifdef __GNUC__ /* Only support GCC inline asm for now */ #if (uECC_ASM && (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ uECC_PLATFORM == uECC_arm_thumb2)) #include "asm_arm.inc" diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h index 173bc12b68f..d580bf44a8c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h @@ -29,11 +29,7 @@ uECC_asm_fast - Use GCC inline assembly optimized for maximum speed. */ #define uECC_asm_small 1 #define uECC_asm_fast 2 #ifndef uECC_ASM - #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) && defined(__GNUC__) /* Only support GCC inline asm for now */ - #define uECC_ASM uECC_asm_fast - #else // DG: ARMCC 5, unlike GCC, IAR and CLANG, doesn't support GNU-style inline assembly - #define uECC_ASM uECC_asm_none - #endif + #define uECC_ASM uECC_asm_fast #endif /* Curve selection options. */ From fbf55f90eb1eb308ddf0ec2b4a7d8eafc7f67c9b Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 12:07:12 +0100 Subject: [PATCH 18/38] change fake chci into custom chci to resolve naming issues --- .../stack/controller/sources/common/chci/chci_tr.c | 8 ++++---- .../{fake_lhci_drv.cpp => custom_chci_tr.cpp} | 12 +++++++++--- .../{fake_lhci_drv.h => custom_chci_tr.h} | 12 +++++++----- .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 2 +- .../TARGET_NRF5x/NRFCordioHCITransportDriver.cpp | 4 ++-- 5 files changed, 23 insertions(+), 15 deletions(-) rename features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/{fake_lhci_drv.cpp => custom_chci_tr.cpp} (84%) rename features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/{fake_lhci_drv.h => custom_chci_tr.h} (82%) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c index 391e9d69ac0..e3c3c3de211 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c @@ -39,8 +39,8 @@ #if (CHCI_TR_CUSTOM == 1) /* Custom transport */ -extern void ChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen); -extern void ChciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData); +extern void CustomChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen); +extern void CustomChciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData); #endif /************************************************************************************************** @@ -430,7 +430,7 @@ static void chciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData #endif #if (CHCI_TR_CUSTOM == 1) - ChciTrWrite(prot, type, len, pData); + CustomChciTrWrite(prot, type, len, pData); #endif } @@ -508,7 +508,7 @@ void ChciTrHandlerInit(wsfHandlerId_t handlerId, uint16_t maxAclLen, uint16_t ma /* Start receiver. */ chciRxPacketSM(); #elif (CHCI_TR_CUSTOM == 1) - ChciTrInit(maxAclLen, maxIsoSduLen); + CustomChciTrInit(maxAclLen, maxIsoSduLen); #else (void)chciRxPacketSM; (void)chciTxComplete; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp similarity index 84% rename from features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.cpp rename to features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp index 1db93a7e343..a145b0835ba 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp @@ -15,7 +15,7 @@ */ #include "mbed.h" -#include "fake_lhci_drv.h" +#include "custom_chci_tr.h" #include "chci_tr.h" #include "chci_api.h" #include "hci_defs.h" @@ -25,7 +25,7 @@ extern "C" { #endif -uint16_t FakeChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *pData) +uint16_t CustomChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *pData) { uint8_t controller_type; switch (hci_type) { @@ -49,7 +49,7 @@ uint16_t FakeChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *p return len; } -uint16_t FakeChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, uint8_t *pData) +uint16_t CustomChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, uint8_t *pData) { uint8_t hci_type; switch (controller_type) { @@ -72,6 +72,12 @@ uint16_t FakeChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, ui return ControllerToHostWrite(prot, hci_type, len, pData); } +void CustomChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen) +{ + (void)maxAclLen; + (void)maxIsoSduLen; +} + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.h similarity index 82% rename from features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.h rename to features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.h index 3d572f4e03b..c237b4c4a36 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/fake_lhci_drv.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef FAKE_LHCI_DRV_H_ -#define FAKE_LHCI_DRV_H_ +#ifndef CUSTOM_CHCI_TR_H_ +#define CUSTOM_CHCI_TR_H_ #ifdef __cplusplus extern "C" { @@ -41,7 +41,7 @@ uint16_t ControllerToHostWrite(uint8_t prot, uint8_t hci_type, uint16_t len, uin * @param pData Data to be sent. * @return Number of bytes processed. */ -uint16_t FakeChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *pData); +uint16_t CustomChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *pData); /** * Send bytes from controller to host. @@ -52,10 +52,12 @@ uint16_t FakeChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t *p * @param pData Data to be sent. * @return Number of bytes processed. */ -uint16_t FakeChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, uint8_t *pData); +uint16_t CustomChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, uint8_t *pData); + +void CustomChciTrInit(uint16_t maxAclLen, uint16_t maxIsoSduLen); #ifdef __cplusplus }; #endif -#endif /* FAKE_LHCI_DRV_H_ */ +#endif /* CUSTOM_CHCI_TR_H_ */ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index 1ce335e6709..b06d2a08f6d 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -27,7 +27,7 @@ // Cordio Includes #include "ll_init_api.h" #include "ll_defs.h" -#include "fake_lhci_drv.h" +#include "custom_chci_tr.h" #include "pal_bb.h" #include "pal_cfg.h" #include "lhci_api.h" diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCITransportDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCITransportDriver.cpp index ff52bfe4600..b367ada564b 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCITransportDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCITransportDriver.cpp @@ -23,7 +23,7 @@ #include "wsf_math.h" #include "chci_api.h" #include "chci_tr.h" -#include "fake_lhci_drv.h" +#include "custom_chci_tr.h" #include "hci_defs.h" #include @@ -47,7 +47,7 @@ void NRFCordioHCITransportDriver::terminate() uint16_t NRFCordioHCITransportDriver::write(uint8_t hci_type, uint16_t len, uint8_t *pData) { /* ownership of the WSF buffer is transferred to the controller (zero copy HCI) */ - return FakeChciTrRead(CHCI_TR_PROT_BLE, hci_type, len, pData); + return CustomChciTrRead(CHCI_TR_PROT_BLE, hci_type, len, pData); } extern "C" void chciDrvInit(void) From c2ccc30657553c1f4e8f0d370ae4a0f061796e99 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 12:07:26 +0100 Subject: [PATCH 19/38] enable custom hci transport in config --- features/FEATURE_BLE/targets/TARGET_CORDIO_LL/mbed_lib.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/mbed_lib.json b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/mbed_lib.json index f132dc33f93..6f82ad050df 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/mbed_lib.json +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/mbed_lib.json @@ -50,6 +50,11 @@ "help": "Does the board have a UART HCI. Valid values are 0 and 1 (must provide UART through PAL).", "value": 0, "macro_name": "CHCI_TR_UART" + }, + "custom-hci-transport": { + "help": "This enables transport through port provided functions, do not disable unless you wish you use uart-hci.", + "value": 1, + "macro_name": "CHCI_TR_CUSTOM" } } } \ No newline at end of file From 4ce36b3728f99b41adeab7a1294927930128d4f9 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 13:15:03 +0100 Subject: [PATCH 20/38] missing def arm id in ll_defs --- .../targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h index c1d67335b39..03c81f1bb84 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/wsf/include/ll_defs.h @@ -45,6 +45,8 @@ extern "C" { #define LL_VER_BT_CORE_SPEC_5_2 0x0B /*!< Bluetooth core specification 5.2 */ #define LL_VER_BT_CORE_SPEC_SYDNEY 0x0C /*!< Bluetooth core specification Sydney */ +#define LL_COMP_ID_ARM 0x005F /*!< ARM Ltd. company ID. */ + /*** Common ***/ #define LL_RSSI_MIN -127 /*!< Minimum RSSI value. */ From 568d0a287ef04d4687dee8b8c3baaf4c495f53ea Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 13:15:28 +0100 Subject: [PATCH 21/38] use assembly on gcc --- .../targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c index 6ae4c45193a..ea351a6e43c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC.c @@ -471,7 +471,7 @@ void uECC_set_rng(uECC_RNG_Function rng_function) { g_rng_function = rng_function; } -#ifdef __GNUC__ /* Only support GCC inline asm for now */ +#if defined __GNUC__ && !defined(__ARMCC_VERSION) /* Only support GCC inline asm for now */ #if (uECC_ASM && (uECC_PLATFORM == uECC_avr)) #include "asm_avr.inc" #endif From 7f23b6df0ff57a1633c508c8df6b5d2a71f0e183 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 13:16:21 +0100 Subject: [PATCH 22/38] update nrf cordio ll files --- .../TARGET_NRF5x/stack/include/audio_board.h | 49 - .../TARGET_NRF5x/stack/sources/pal_bb.c | 71 +- .../TARGET_NRF5x/stack/sources/pal_bb_ble.c | 962 +++++++++++------- .../stack/sources/pal_bb_ble_rf.c | 142 ++- .../TARGET_NRF5x/stack/sources/pal_cfg.c | 131 ++- .../TARGET_NRF5x/stack/sources/pal_crypto.c | 295 ++++-- .../TARGET_NRF5x/stack/sources/pal_led.c | 338 +++--- .../TARGET_NRF5x/stack/sources/pal_rtc.c | 197 +++- .../TARGET_NRF5x/stack/sources/pal_sys.c | 164 +-- .../TARGET_NRF5x/stack/sources/pal_timer.c | 272 +++-- .../TARGET_NRF5x/stack/sources/pal_twi.c | 206 ++-- .../TARGET_NRF5x/stack/sources/pal_uart.c | 309 +++--- 12 files changed, 1836 insertions(+), 1300 deletions(-) delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/include/audio_board.h diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/include/audio_board.h b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/include/audio_board.h deleted file mode 100644 index 05cb6ce0852..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/include/audio_board.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief Audio board definition. - * - * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#ifndef AUDIOBOARD_H -#define AUDIOBOARD_H - -#include "stack/platform/include/pal_types.h" -#include "nrf_gpio.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#define AUDIO_LED_1 NRF_GPIO_PIN_MAP(1,1) -#define AUDIO_LED_2 NRF_GPIO_PIN_MAP(1,2) -#define AUDIO_LED_3 NRF_GPIO_PIN_MAP(1,3) -#define AUDIO_LED_4 NRF_GPIO_PIN_MAP(1,4) -#define AUDIO_LED_5 NRF_GPIO_PIN_MAP(1,5) -#define AUDIO_LED_6 NRF_GPIO_PIN_MAP(1,6) - -#ifdef __cplusplus -}; -#endif - -#endif /* AUDIOBOARD_H */ diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb.c index f9ed39323a4..18286bb065e 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb.c @@ -7,12 +7,14 @@ * Copyright (c) 2016-2018 Arm Ltd. All Rights Reserved. * ARM confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,8 +23,9 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_types.h" -#include "stack/platform/include/pal_bb.h" +#include "pal_types.h" +#include "pal_bb.h" +#include "pal_bb.h" #include "nrf.h" #include "nrf_timer.h" #include @@ -51,8 +54,6 @@ static bbDrvIrqCback_t palBbRadioIrqCbackTbl[BB_PROT_NUM]; /*! * \brief Initialize the baseband driver. * - * \return None. - * * One-time initialization of baseband resources. This routine can be used to setup baseband * resources, load RF trim parameters and execute RF calibrations. * @@ -63,6 +64,10 @@ void PalBbInit(void) { palBbEnableCnt = 0; + /* Cycle radio peripheral power to guarantee known radio state. */ + NRF_RADIO->POWER = 0; + NRF_RADIO->POWER = 1; + memset(palBbTimerIrqCbackTbl, 0, sizeof(palBbTimerIrqCbackTbl)); memset(palBbRadioIrqCbackTbl, 0, sizeof(palBbRadioIrqCbackTbl)); } @@ -71,8 +76,6 @@ void PalBbInit(void) /*! * \brief Enable the BB hardware. * - * \return None. - * * This routine brings the BB hardware out of low power (enable power and clocks) just before a * first BB operation is executed. */ @@ -86,15 +89,13 @@ void PalBbEnable(void) /*! * \brief Disable the BB hardware. * - * \return None. - * * This routine signals the BB hardware to go into low power (disable power and clocks) after all * BB operations have been disabled. */ /*************************************************************************************************/ void PalBbDisable(void) { - if(palBbEnableCnt) + if (palBbEnableCnt) { palBbEnableCnt--; } @@ -105,8 +106,6 @@ void PalBbDisable(void) * \brief Load BB timing configuration. * * \param pCfg Return configuration values. - * - * \return None. */ /*************************************************************************************************/ void PalBbLoadCfg(PalBbCfg_t *pCfg) @@ -115,27 +114,34 @@ void PalBbLoadCfg(PalBbCfg_t *pCfg) pCfg->rfSetupDelayUsec = BB_RF_SETUP_DELAY_US; pCfg->maxScanPeriodMsec = BB_MAX_SCAN_PERIOD_MS; pCfg->schSetupDelayUsec = BB_SCH_SETUP_DELAY_US; +#if (BB_CLK_RATE_HZ == 32768) + pCfg->BbTimerBoundaryUsec = BB_RTC_MAX_VALUE_US; +#elif (BB_CLK_RATE_HZ == 8000000) + pCfg->BbTimerBoundaryUsec = BB_TIMER_8MHZ_MAX_VALUE_US; +#elif (BB_CLK_RATE_HZ == 1000000) + pCfg->BbTimerBoundaryUsec = BB_TIMER_1MHZ_MAX_VALUE_US; +#else + #error "Unsupported platform." +#endif } /*************************************************************************************************/ /*! - * \brief Get the current BB clock value. - * - * \param useRtcBBClk Use RTC BB clock. + * \brief Get the current BB clock value in microseconds. * * \return Current BB clock value, units are microseconds. * * This routine reads the current value from the BB clock and returns its value. */ /*************************************************************************************************/ -uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk) +uint32_t PalBbGetCurrentTime(void) { if (palBbEnableCnt > 0) { - if (useRtcBBClk) + if (USE_RTC_BB_CLK) { /* return the RTC counter value */ - return NRF_RTC0->COUNTER; + return BB_TICKS_TO_US(NRF_RTC1->COUNTER); } else { @@ -143,7 +149,7 @@ uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk) nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); /* Read and return the captured count value from capture register 3 */ - return nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3); + return BB_TICKS_TO_US(nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3)); } } return 0; @@ -151,7 +157,7 @@ uint32_t PalBbGetCurrentTime(bool_t useRtcBBClk) /*************************************************************************************************/ /*! - * \brief Get the current FRC time. + * \brief Get the current FRC time tick. * * \param pTime Pointer to return the current time. * @@ -167,11 +173,22 @@ bool_t PalBbGetTimestamp(uint32_t *pTime) { if (palBbEnableCnt == 0) { - *pTime = 0; return FALSE; } - *pTime = PalBbGetCurrentTime(USE_RTC_BB_CLK); + if (USE_RTC_BB_CLK && pTime) + { + /* return the RTC counter value */ + *pTime = NRF_RTC1->COUNTER; + } + else if (pTime) + { + /* Capture current TIMER0 count to capture register 3 */ + nrf_timer_task_trigger(NRF_TIMER0, NRF_TIMER_TASK_CAPTURE3); + + /* Read and return the captured count value from capture register 3 */ + *pTime = nrf_timer_cc_read(NRF_TIMER0, NRF_TIMER_CC_CHANNEL3); + } return TRUE; } @@ -183,8 +200,6 @@ bool_t PalBbGetTimestamp(uint32_t *pTime) * \param protId Protocol ID. * \param timerCback Timer IRQ callback. * \param radioCback Timer IRQ callback. - * - * \return None. */ /*************************************************************************************************/ void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCback_t radioCback) @@ -198,8 +213,6 @@ void PalBbRegisterProtIrq(uint8_t protId, bbDrvIrqCback_t timerCback, bbDrvIrqCb * \brief Set protocol ID. * * \param protId Protocol ID. - * - * \return None. */ /*************************************************************************************************/ void PalBbSetProtId(uint8_t protId) @@ -210,8 +223,6 @@ void PalBbSetProtId(uint8_t protId) /*************************************************************************************************/ /*! * \brief Combined BLE and 154 radio interrupt handler. - * - * \return None. */ /*************************************************************************************************/ void RADIO_IRQHandler(void) @@ -225,8 +236,6 @@ void RADIO_IRQHandler(void) /*************************************************************************************************/ /*! * \brief Combined BLE and 154 timer interrupt handler. - * - * \return None. */ /*************************************************************************************************/ void TIMER0_IRQHandler(void) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble.c index cd033fbbc70..35452d15f65 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble.c @@ -5,14 +5,15 @@ * \brief Baseband driver interface file. * * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -41,24 +42,34 @@ * PPI Channel 15: * Used to trigger timer capture to CC[2] on every radio PAYLOAD event. * + * If BB_CLK_RATE_HZ == 32768 (low power mode): + * + * Additional two channels of NRF RTC1 are controlled here. + * CC[1] - Compare value for NRF timer0 start task. + * CC[2] - Compare value for NRF HFCLK start task. */ -#include "stack/platform/include/pal_types.h" -#include "stack/platform/include/pal_bb.h" -#include "stack/platform/include/pal_rtc.h" -#include "stack/platform/include/pal_led.h" -#include "stack/platform/include/pal_bb_ble.h" -#include "stack/platform/include/pal_radio.h" +#include "pal_types.h" +#include "pal_bb.h" +#include "pal_rtc.h" +#include "pal_bb.h" +#include "pal_led.h" +#include "pal_bb_ble.h" +#include "pal_radio.h" #include "ll_defs.h" -#include "boards.h" #include "nrf.h" #include "nrf_gpio.h" #include "nrf_gpiote.h" #include +#if (LL_ENABLE_TESTER) +#include "ll_tester_api.h" +#endif + /************************************************************************************************** Macros **************************************************************************************************/ + #define PDU_HEADER_LEN 2 #define MAX_PAYLOAD_LEN 255 #define BB_DATA_PDU_LEN_OFFSET 1 @@ -92,13 +103,13 @@ /* scratch area for Nordic encryption engine */ #define ENC_CCM_DATA_STRUCT_LEN 33 /* length of CCM data structure used for encryption/decryption */ -#define ENC_SCRATCH_BUF_LEN 43 /* size of scratch area */ -#define ENC_MAX_PAYLOAD_LEN 27 /* maximum size of payload that can be encrypted/decrytped */ +#define ENC_MAXPACKETSIZE 251 /* length used in MAXPACKETSIZE */ +#define ENC_SCRATCH_BUF_LEN ( 16 + ENC_MAXPACKETSIZE ) /* size of scratch area */ #define ENC_H_FIELD_LEN 1 /* length of "H" field */ #define ENC_LPLUS4_LEN 1 /* length of the "L+4" field */ #define ENC_RFU_LEN 1 /* length of the "RFU" field */ #define ENC_MIC_LEN 4 /* length of the MIC field */ -#define ENC_TX_BUF_LEN ( ENC_H_FIELD_LEN + ENC_LPLUS4_LEN + ENC_RFU_LEN + ENC_MAX_PAYLOAD_LEN ) +#define ENC_TX_BUF_LEN ( ENC_H_FIELD_LEN + ENC_LPLUS4_LEN + ENC_RFU_LEN + ENC_MAXPACKETSIZE ) #define ENC_OUTPUT_BUF_LEN ( ENC_TX_BUF_LEN + ENC_MIC_LEN ) /* +/- range for TIFS adjustment */ @@ -125,15 +136,7 @@ #endif #if (USE_RTC_BB_CLK) -uint32_t USEC_TO_TICKS(uint32_t usec) -{ - uint64_t ticks; /* use long integer so no loss of precision */ - ticks = (uint64_t)usec << UINT64_C(9); /* multiply by 512 */ - ticks /= 15625; - return ticks; -} -#else - #define USEC_TO_TICKS(usec) ((usec) * TICKS_PER_USEC) + #define TICKS_TO_USEC(ticks) (ticks) /* Use 1MHz for HFCLK */ #endif #if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) @@ -152,6 +155,39 @@ uint32_t USEC_TO_TICKS(uint32_t usec) #define BB_ENABLE_INLINE_DEC_RX FALSE #endif +#ifndef DIAG_PINS_ENA +#define DIAG_PINS_ENA 1 +#endif + +/* LED definitions */ +#ifndef BB_LED_ENA +#define BB_LED_ENA 0 +#endif + +#if (BB_LED_ENA == 1) +#define BB_LED_1M_ON() PalLedOn(0) +#define BB_LED_2M_ON() PalLedOn(1) +#define BB_LED_CODED_ON() PalLedOn(0); PalLedOn(1) +#define BB_LED_OFF() PalLedOff(0); PalLedOff(1) +#else +#define BB_LED_1M_ON() +#define BB_LED_2M_ON() +#define BB_LED_CODED_ON() +#define BB_LED_OFF() +#endif + +#if (AUDIO_CAPE == 1) +#define BB_LED_TX_ON() PalLedOn(6) +#define BB_LED_TX_OFF() PalLedOff(6) +#define BB_LED_RX_ON() PalLedOn(7) +#define BB_LED_RX_OFF() PalLedOff(7) +#else +#define BB_LED_TX_ON() +#define BB_LED_TX_OFF() +#define BB_LED_RX_ON() +#define BB_LED_RX_OFF() +#endif + /*! \brief convert little endian byte buffer to uint16_t. */ #define BYTES_TO_UINT16(n, p) {n = ((uint16_t)(p)[0] + ((uint16_t)(p)[1] << 8));} @@ -178,7 +214,6 @@ typedef enum TIFS_RX_RAMPUP } bbTifsState_t; - /************************************************************************************************** Local Functions **************************************************************************************************/ @@ -195,6 +230,7 @@ static void BbBleDrvRadioIRQHandler(void); /************************************************************************************************** Local Variables **************************************************************************************************/ + volatile bbDriverState_t driverState = NULL_STATE; volatile bbTifsState_t tifsState; uint8_t bbRadioPcnf1WhiteEn; @@ -202,7 +238,7 @@ PalBbBleTxIsr_t bbTxCallback = NULL; PalBbBleRxIsr_t bbRxCallback = NULL; uint32_t bbRxTimeoutUsec; uint8_t * bbpRxBuf; -uint32_t bbAntennaDueTime; +uint32_t bbAntennaDueTimeUsec; uint32_t bbEventStartTime; uint16_t bbDueOffsetUsec; int8_t bbTxTifsAdj; @@ -222,6 +258,7 @@ uint8_t bbEncryptCcmData[ENC_CCM_DATA_STRUCT_LEN]; uint8_t bbTrlSave[BB_TRL_MAX_LEN]; uint8_t *bbTrlSavedPtr = NULL; uint8_t bbTrlSavedLen; +PalBbBleOpParam_t bbOpParam; #ifndef BB_ASSERT_ENABLED #define BB_ASSERT_ENABLED FALSE @@ -254,6 +291,8 @@ uint64_t bbRxAccAddrInvalidChanMask = 0; bool_t bbTxAccAddrShiftMask = FALSE; bool_t bbRxAccAddrShiftMask = FALSE; bool_t bbTxAccAddrShiftInc = FALSE; +bool_t invalidateAccAddrOnceRx = FALSE; +bool_t invalidateAccAddrOnceTx = FALSE; #endif /* enable BB assertions */ @@ -344,62 +383,58 @@ uint16_t diagCancels = 0; #endif ///////////////////////////////////////////////////////////////////////////////// -#define DIAG_USER_DEBUG_PINS_ENA 0 - -#define DIAG_PINS_ENA 0 - -#if DIAG_PINS_ENA -#if defined(BOARD_PCA10028) - -#define TX_PIN 12 /* P0.12 */ -#define RX_PIN 13 /* P0.13 */ -#define RADIO_READY_TOGGLE_PIN 15 /* P0.15 */ -#define RADIO_END_TOGGLE_PIN 16 /* P0.16 */ -#define RADIO_INT_PIN 17 /* P0.17 */ -#define TIMER0_INT_PIN 18 /* P0.18 */ - -#define DIAG_PIN_SET(x) { nrf_gpio_pin_set(x); } -#define DIAG_PIN_CLEAR(x) { nrf_gpio_pin_clear(x); } - -#elif defined(BOARD_PCA10040) - -#define TX_PIN 11 /* P0.11 */ -#define RX_PIN 12 /* P0.12 */ -#define RADIO_READY_TOGGLE_PIN 13 /* P0.13 */ -#define RADIO_END_TOGGLE_PIN 14 /* P0.14 */ -#define RADIO_INT_PIN 0 /* P0.00 */ -#define TIMER0_INT_PIN 1 /* P0.01 */ - -#define DIAG_PIN_SET(x) { nrf_gpio_pin_set(x); } -#define DIAG_PIN_CLEAR(x) { nrf_gpio_pin_clear(x); } -#elif defined(BOARD_PCA10056) - -#define TX_PIN 3 /* P0.03 */ -#define RX_PIN 4 /* P0.04 */ -#define RADIO_READY_TOGGLE_PIN 30 /* P0.30 */ -#define RADIO_END_TOGGLE_PIN 31 /* P0.31 */ -#define RADIO_INT_PIN 29 /* P0.29 */ -#define TIMER0_INT_PIN 28 /* P0.28 */ - -#define DIAG_USER_DEBUG_PINS_ENA 1 -#define USER_DEBUG_0_PIN 35 /* P1.03 */ -#define USER_DEBUG_1_PIN 36 /* P1.04 */ -#define USER_DEBUG_2_PIN 37 /* P1.05 */ -#define USER_DEBUG_3_PIN 38 /* P1.06 */ - -#define DIAG_PIN_SET(x) { nrf_gpio_pin_set(x); } -#define DIAG_PIN_CLEAR(x) { nrf_gpio_pin_clear(x); } -#else -#error "Diagnostic pins not supported on board" -#endif +/*************************************************************************************************/ +/*! + * \brief Config GPIO as input or output. + * + * \param pin Pin number. + */ +/*************************************************************************************************/ +void PalBbGpioCfgOutput(uint32_t pin) +{ + nrf_gpio_cfg_output(pin); +} -#else // DIAG_PINS_ENA +/*************************************************************************************************/ +/*! + * \brief Set GPIO pin high. + * + * \param pin Pin number. + */ +/*************************************************************************************************/ +void PalBbGpioSet(uint32_t pin) +{ + nrf_gpio_pin_write(pin, 1); +} -#define DIAG_PIN_SET(x) -#define DIAG_PIN_CLEAR(x) -#endif // DIAG_PINS_ENA +/*************************************************************************************************/ +/*! + * \brief Set GPIO pin low. + * + * \param pin Pin number. + */ +/*************************************************************************************************/ +void PalBbGpioClear(uint32_t pin) +{ + nrf_gpio_pin_write(pin, 0); +} -///////////////////////////////////////////////////////////////////////////////// +/*************************************************************************************************/ +/*! + * \brief Toggle GPIO. + * + * \param pin Pin number. + * \param times GPIO toggle times. + */ +/*************************************************************************************************/ +void PalBbGpioToggle(uint32_t pin, uint32_t times) +{ + for (uint32_t i = 0; i < times; i++) + { + nrf_gpio_pin_write(pin, 1); + nrf_gpio_pin_write(pin, 0); + } +} /*************************************************************************************************/ /*! @@ -407,8 +442,6 @@ uint16_t diagCancels = 0; * * \param phy PHY. * \param option PHY option. - * - * \return None. */ /*************************************************************************************************/ static inline void palBbSetRadioMode(uint8_t phy, uint8_t option) @@ -419,11 +452,7 @@ static inline void palBbSetRadioMode(uint8_t phy, uint8_t option) NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit; break; -#if defined(NRF52832_XXAA) - case BB_PHY_BLE_2M: - NRF_RADIO->MODE = RADIO_MODE_MODE_Nrf_2Mbit; - break; -#elif defined(NRF52840_XXAA) +#if defined(NRF52832_XXAA) || defined(NRF52840_XXAA) case BB_PHY_BLE_2M: NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_2Mbit; break; @@ -447,6 +476,22 @@ static inline void palBbSetRadioMode(uint8_t phy, uint8_t option) break; } + /* select LED according to client selection not actual PHY used */ + switch (bbRxPhy) + { + case BB_PHY_BLE_1M: + BB_LED_1M_ON(); + break; + case BB_PHY_BLE_2M: + BB_LED_2M_ON(); + break; + case BB_PHY_BLE_CODED: + BB_LED_CODED_ON(); + break; + default: + break; + } + #if defined(NRF52832_XXAA) *(volatile uint32_t*)0x40001777 = 0UL; /* Disable fault tolerant AA correlator. */ #endif @@ -455,38 +500,36 @@ static inline void palBbSetRadioMode(uint8_t phy, uint8_t option) #if (USE_RTC_BB_CLK) /*************************************************************************************************/ /*! - * \brief Set the time for the HFCLK to start. + * \brief Set the time for the timer0 to start. * - * \param startTime HFCLK start time. + * \param startTime timer0 start time. * - * \return None. - * - * Setup the RTC clock to start the HFCLK. */ /*************************************************************************************************/ -static void palBbSetHfClkStart(uint32_t startTime) +static void palBbStartTimer(uint32_t startTime) { - bbEventStartTime = NRF_RTC0->CC[1] = startTime; - NRF_RTC0->EVENTS_COMPARE[1] = 0; - WAIT_FOR_WR_BUF_EMPTY(NRF_RTC0->EVENTS_COMPARE[1]); - - uint32_t rtcNow = NRF_RTC0->COUNTER; - if (((startTime - rtcNow) & PAL_MAX_RTC_COUNTER_VAL) <= HFCLK_OSC_SETTLE_TICKS) - { - /* not enough time for oscillator to settle; leave HFCLK running */ - return; - } - - NRF_CLOCK->TASKS_HFCLKSTOP = 1; - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - WAIT_FOR_WR_BUF_EMPTY(NRF_CLOCK->EVENTS_HFCLKSTARTED); - - NRF_RTC0->CC[2] = (startTime - HFCLK_OSC_SETTLE_TICKS) & PAL_MAX_RTC_COUNTER_VAL; - NRF_RTC0->EVENTS_COMPARE[2] = 0; - WAIT_FOR_WR_BUF_EMPTY(NRF_RTC0->EVENTS_COMPARE[2]); + bbEventStartTime = NRF_RTC1->CC[1] = startTime; + NRF_RTC1->EVENTS_COMPARE[1] = 0; + WAIT_FOR_WR_BUF_EMPTY(NRF_RTC1->EVENTS_COMPARE[1]); } #endif +/*************************************************************************************************/ +/*! + * \brief Low power operation. + * + * \note Called by upper baseband code. + */ +/*************************************************************************************************/ +void PalBbBleLowPower(void) +{ + /* Stop high frequency timer between BLE events if low lower mode. */ +#if (USE_RTC_BB_CLK) + NRF_TIMER0->TASKS_STOP = 1; + NRF_TIMER0->TASKS_CLEAR = 1; +#endif +} + #if (BB_ENABLE_INLINE_ENC_TX || BB_ENABLE_INLINE_DEC_RX) /*************************************************************************************************/ /*! @@ -494,8 +537,6 @@ static void palBbSetHfClkStart(uint32_t startTime) * * \param enable Boolean flag to enable or disable TX encryption * - * \return None. - * */ /*************************************************************************************************/ static void palBbBleInlineEncryptTxEnable(bool_t enable) @@ -504,16 +545,6 @@ static void palBbBleInlineEncryptTxEnable(bool_t enable) /* copy encryption enable to global variable */ bbEncryptTxFlag = enable; - - /* set or clear enable of encryption on transmit */ - if (enable) - { - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Enabled; - } - else - { - NRF_CCM->ENABLE = CCM_ENABLE_ENABLE_Disabled; - } } /*************************************************************************************************/ @@ -522,8 +553,6 @@ static void palBbBleInlineEncryptTxEnable(bool_t enable) * * \param enable Boolean flag to indicate if MIC is suppressed * - * \return None. - * */ /*************************************************************************************************/ static void palBbBleInlineEncryptDecryptSuppressMic(bool_t enable) @@ -540,14 +569,10 @@ static void palBbBleInlineEncryptDecryptSuppressMic(bool_t enable) * * \param key Pointer to 16-byte key value * - * \return None. - * */ /*************************************************************************************************/ -static void palBbBleInlineEncryptDecryptSetKey(uint8_t * key) +static void palBbBleInlineEncryptDecryptSetKey(uint8_t *pKey) { - uint8_t i; - BB_ASSERT(driverState == IDLE_STATE); /* driver must be idle */ #if BB_ASSERT_ENABLED == TRUE @@ -555,9 +580,9 @@ static void palBbBleInlineEncryptDecryptSetKey(uint8_t * key) #endif /* populate encryption structure with reversed stored key */ - for (i=0; i<16; i++) + for (unsigned int i=0; i<16; i++) { - bbEncryptCcmData[i] = key[15-i]; + bbEncryptCcmData[i] = pKey[15-i]; } } @@ -567,11 +592,9 @@ static void palBbBleInlineEncryptDecryptSetKey(uint8_t * key) * * \param key Pointer to 8-byte value for IV * - * \return None. - * */ /*************************************************************************************************/ -static void palBbBleDrvInlineEncryptDecryptSetIv(uint8_t * iv) +static void palBbBleDrvInlineEncryptDecryptSetIv(uint8_t *pIV) { BB_ASSERT(driverState == IDLE_STATE); /* driver must be idle */ @@ -579,10 +602,9 @@ static void palBbBleDrvInlineEncryptDecryptSetIv(uint8_t * iv) ivSetFlag = 1; #endif - /* copy the 8-byte initialization vector */ - memcpy(&bbEncryptCcmData[25], iv, 8); + /* populate encryption structure with reversed stored IV */ + memcpy(&bbEncryptCcmData[25], pIV, 8); } -#endif /*************************************************************************************************/ /*! @@ -590,8 +612,6 @@ static void palBbBleDrvInlineEncryptDecryptSetIv(uint8_t * iv) * * \param dir 0=slave, non-zero=master * - * \return None. - * */ /*************************************************************************************************/ void PalBbBleInlineEncryptDecryptSetDirection(uint8_t dir) @@ -613,8 +633,6 @@ void PalBbBleInlineEncryptDecryptSetDirection(uint8_t dir) * * \param count Packet counter value, a 39-bit value * - * \return None. - * */ /*************************************************************************************************/ void PalBbBleInlineEncryptSetPacketCount(uint64_t count) @@ -632,13 +650,12 @@ void PalBbBleInlineEncryptSetPacketCount(uint64_t count) bbEncryptCcmData[19] = (count >> 24) & 0xFF; bbEncryptCcmData[20] = (count >> 32) & 0x7F; /* only 7-bits of MSB are used (packet count is 39 bits) */ } +#endif /*************************************************************************************************/ /*! * \brief Initialize the BLE baseband driver. * - * \return None. - * * One-time initialization of BLE baseband driver. */ /*************************************************************************************************/ @@ -680,13 +697,6 @@ void PalBbBleInit(void) /* enable receive address on logical address 0 (uses PREFIX0.AP0/BASE0 pair) */ NRF_RADIO->RXADDRESSES = 1; /* NOTE: this is a bitmask, a '1' enables logical address 0 */ - /* configure CCM hardware */ - NRF_CCM->INPTR = (uint32_t)bbEncryptTxBuf; - NRF_CCM->MODE = CCM_MODE_MODE_Encryption; - NRF_CCM->OUTPTR = (uint32_t)bbEncryptOutBuf; - NRF_CCM->SCRATCHPTR = (uint32_t)bbEncryptScratchBuf; - NRF_CCM->CNFPTR = (uint32_t)bbEncryptCcmData; - /* set default direction in CCM structure */ bbEncryptCcmData[24] = 0; /* 0=slave, 1=master */ @@ -700,8 +710,8 @@ void PalBbBleInit(void) bbEncryptTxFlag = 0; #if (USE_RTC_BB_CLK) - NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; - NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; #endif /* update driver state */ @@ -716,50 +726,6 @@ void PalBbBleInit(void) #endif ///////////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////////// - #if DIAG_PINS_ENA - /* initialize diagnostics pins */ - nrf_gpio_cfg_output(TX_PIN); - nrf_gpio_cfg_output(RX_PIN); - nrf_gpio_cfg_output(RADIO_READY_TOGGLE_PIN); - nrf_gpio_cfg_output(RADIO_END_TOGGLE_PIN); - nrf_gpio_cfg_output(RADIO_INT_PIN); - nrf_gpio_cfg_output(TIMER0_INT_PIN); - - /* initialize PPI/GPIOTE to toggle pin on every radio READY event */ - #define READY_GPIOTE_CHAN 0 - NRF_PPI->CH[11].EEP = (uint32_t)&NRF_RADIO->EVENTS_READY; - NRF_PPI->CH[11].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[READY_GPIOTE_CHAN]; - NRF_PPI->CHENSET = PPI_CHENSET_CH11_Msk; - - nrf_gpiote_task_configure( READY_GPIOTE_CHAN, - RADIO_READY_TOGGLE_PIN, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_LOW ); - nrf_gpiote_task_enable( READY_GPIOTE_CHAN ); - - /* initialize PPI/GPIOTE to toggle pin on every radio END event */ - #define END_GPIOTE_CHAN 1 - NRF_PPI->CH[12].EEP = (uint32_t)&NRF_RADIO->EVENTS_END; - NRF_PPI->CH[12].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[END_GPIOTE_CHAN]; - NRF_PPI->CHENSET = PPI_CHENSET_CH12_Msk; - - nrf_gpiote_task_configure( END_GPIOTE_CHAN, - RADIO_END_TOGGLE_PIN, - NRF_GPIOTE_POLARITY_TOGGLE, - NRF_GPIOTE_INITIAL_VALUE_LOW ); - nrf_gpiote_task_enable( END_GPIOTE_CHAN ); - #endif - ///////////////////////////////////////////////////////////////////////////////// - - #if DIAG_USER_DEBUG_PINS_ENA - /* initialize diagnostics pins for user-debug. */ - nrf_gpio_cfg_output(USER_DEBUG_0_PIN); - nrf_gpio_cfg_output(USER_DEBUG_1_PIN); - nrf_gpio_cfg_output(USER_DEBUG_2_PIN); - nrf_gpio_cfg_output(USER_DEBUG_3_PIN); - #endif - bbTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; bbRxPhyOptions = BB_PHY_OPTIONS_DEFAULT; tifsTxPhyOptions = BB_PHY_OPTIONS_DEFAULT; @@ -772,8 +738,6 @@ void PalBbBleInit(void) /*! * \brief Enable the BB hardware. * - * \return None. - * * Wake the BB hardware out of sleep and enable for operation. All BB functionality is * available when this routine completes. BB clock is set to zero and started. */ @@ -787,7 +751,13 @@ void PalBbBleEnable(void) BB_ASSERT(NVIC_GetPriority(RADIO_IRQn) == NVIC_GetPriority(TIMER0_IRQn)); /* BB driver related interrupts must have same priority */ BB_ASSERT(driverState == SLEEP_STATE); /* the BB driver should never be re-enabled */ BB_ASSERT(NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk); /* HF clock must be running */ -#if (!USE_RTC_BB_CLK) +#if (USE_RTC_BB_CLK) + if (!(NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk)) + { + NRF_CLOCK->TASKS_HFCLKSTART = 1; + } + +#else BB_ASSERT(NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_SRC_Msk); /* HF clock source must be the crystal */ #endif @@ -812,12 +782,12 @@ void PalBbBleEnable(void) */ #if (USE_RTC_BB_CLK) /* timer0 starts when RTC0.COMPARE[1] event is triggered */ - NRF_PPI->CH[13].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[1]; + NRF_PPI->CH[13].EEP = (uint32_t) &NRF_RTC1->EVENTS_COMPARE[1]; NRF_PPI->CH[13].TEP = (uint32_t) &NRF_TIMER0->TASKS_START; NRF_PPI->CHENSET = PPI_CHENSET_CH13_Msk; /* enable channel */ /* HFCLK starts when RTC0.COMPARE[2] event is triggered */ - NRF_PPI->CH[10].EEP = (uint32_t) &NRF_RTC0->EVENTS_COMPARE[2]; + NRF_PPI->CH[10].EEP = (uint32_t) &NRF_RTC1->EVENTS_COMPARE[2]; NRF_PPI->CH[10].TEP = (uint32_t) &NRF_CLOCK->TASKS_HFCLKSTART; NRF_PPI->CHENSET = PPI_CHENSET_CH10_Msk; /* enable channel */ #else @@ -876,8 +846,8 @@ void PalBbBleEnable(void) */ #if (USE_RTC_BB_CLK) - NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE1_Msk; - NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE2_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE1_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE2_Msk; #endif /* enable the radio "TIFS Expired" interrupt (triggers on radio PAYLOAD event) */ @@ -904,8 +874,6 @@ void PalBbBleEnable(void) /*! * \brief Disable the BB hardware. * - * \return None. - * * Disable the baseband and put radio hardware to sleep. Must be called from an idle state. * A radio operation cannot be in progress. */ @@ -918,16 +886,15 @@ void PalBbBleDisable(void) palBbRadioHardStop(); /* stop timer */ - NRF_TIMER0->TASKS_STOP = 1; - NRF_TIMER0->TASKS_SHUTDOWN = 1; + PalBbBleLowPower(); /* disable PPI channels */ NRF_PPI->CHENCLR = PPI_CHENCLR_CH14_Msk; /* Chan 14: COMPARE[0] -> TXEN/RXEN */ NRF_PPI->CHENCLR = PPI_CHENCLR_CH15_Msk; /* Chan 15: PAYLOAD -> CAPTURE[2] */ #if (USE_RTC_BB_CLK) - NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; - NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; #endif /* disable and clean up TIMER0 interrupts */ @@ -955,12 +922,9 @@ void PalBbBleDisable(void) * * \param pParam Callback called upon the completion of a transmit operation. * - * \return None. - * * The given \a txCback routine is called once and only once in response to \a BbDrvTx(). It * should be called in the ISR context due to the transmit completion interrupt from the BB. * If \a BbDrvTxCancel() is called with a return value of TRUE, \a txCback must not be executed. - * */ /*************************************************************************************************/ void PalBbBleSetDataParams(const PalBbBleDataParam_t *pParam) @@ -974,15 +938,7 @@ void PalBbBleSetDataParams(const PalBbBleDataParam_t *pParam) bbRxCallback = pParam->rxCback; /* store due time for future use */ - bbAntennaDueTime = pParam->due; - bbDueOffsetUsec = pParam->dueOffsetUsec; - -#if (USE_RTC_BB_CLK) - if (bbDueOffsetUsec > 31) - { - bbDueOffsetUsec = 31; - } -#endif + bbAntennaDueTimeUsec = pParam->dueUsec; /* store timeout value for future use */ bbRxTimeoutUsec = pParam->rxTimeoutUsec; @@ -994,7 +950,7 @@ void PalBbBleSetDataParams(const PalBbBleDataParam_t *pParam) bbRxCallback = DiagFauxRxCallback; diagRxCallback = pParam->rxCback; #endif - // for diagnostic purposes, an override scheme where all callbacks pass through an internal path + /* for diagnostic purposes, an override scheme where all callbacks pass through an internal path. */ ///////////////////////////////////////////////////////////////////////////////// } @@ -1004,14 +960,12 @@ void PalBbBleSetDataParams(const PalBbBleDataParam_t *pParam) * * \param pOpParam Operations parameters. * - * \return None. - * * Calling this routine will set parameters for the next transmit or receive operations. */ /*************************************************************************************************/ void PalBbBleSetOpParams(const PalBbBleOpParam_t *pOpParam) { - + bbOpParam = *pOpParam; } /*************************************************************************************************/ @@ -1019,36 +973,13 @@ void PalBbBleSetOpParams(const PalBbBleOpParam_t *pOpParam) * \brief Set channelization parameters. * * \param pChan Channelization parameters. - * - * \return None. - * - * Calling this routine will set these parameters for all future transmit and receive operations - * until this routine is called again providing new parameters. - * - * The setting of channelization parameters influence the operations of the following listed - * routines. Therefore, this routine is called to set the channel characteristics before - * the use of these listed packet routines. - * - * - \a BbDrvTx() - * - \a BbDrvRx() - * - \a BbDrvTxTifs() - * - \a BbDrvRxTifs() - * - * \note The \a pParam contents are not guaranteed to be static and is only valid in the - * context of the call to this routine. Therefore parameters requiring persistence - * should be copied. */ /*************************************************************************************************/ -void PalBbBleSetChannelParam(PalBbBleChan_t *pChan) +static void palBbBleSetChannelParam(PalBbBleChan_t *pChan) { uint8_t rfChan; int8_t txPower; - BB_ASSERT(driverState == IDLE_STATE); /* driver must be idle */ - - /* stop any TIFS operation that might be ramping up */ - palBbRadioHardStop(); - /* get the channel index into a local variable, for efficiency */ bbChanIndex = pChan->chanIdx; @@ -1151,24 +1082,55 @@ void PalBbBleSetChannelParam(PalBbBleChan_t *pChan) /* set encryption parameters */ if (pChan->enc.enaEncrypt || pChan->enc.enaDecrypt) { - palBbBleInlineEncryptDecryptSuppressMic(pChan->enc.nonceMode); + palBbBleInlineEncryptDecryptSuppressMic(FALSE); /* TODO add MIC suppression */ palBbBleInlineEncryptDecryptSetKey(pChan->enc.sk); palBbBleDrvInlineEncryptDecryptSetIv(pChan->enc.iv); + PalBbBleInlineEncryptDecryptSetDirection(pChan->enc.dir); } #endif } +/*************************************************************************************************/ +/*! + * \brief Set channelization parameters. + * + * \param pChan Channelization parameters. + * + * Calling this routine will set these parameters for all future transmit and receive operations + * until this routine is called again providing new parameters. + * + * The setting of channelization parameters influence the operations of the following listed + * routines. Therefore, this routine is called to set the channel characteristics before + * the use of these listed packet routines. + * + * - \a BbDrvTx() + * - \a BbDrvRx() + * - \a BbDrvTxTifs() + * - \a BbDrvRxTifs() + * + * \note The \a pParam contents are not guaranteed to be static and is only valid in the + * context of the call to this routine. Therefore parameters requiring persistence + * should be copied. + */ +/*************************************************************************************************/ +void PalBbBleSetChannelParam(PalBbBleChan_t *pChan) +{ + BB_ASSERT(driverState == IDLE_STATE); /* driver must be idle */ + + /* stop any TIFS operation that might be ramping up */ + palBbRadioHardStop(); + + palBbBleSetChannelParam(pChan); +} + /*************************************************************************************************/ /*! * \brief Enable or disable data whitening. * * \param enable flag to indicate data whitening * - * \return None. - * * Sets an internal variable that indicates if data whitening is enabled or not. * The value is used later when setting PCNF1 at beginning of TX or RX. - * */ /*************************************************************************************************/ void PalBbBleEnableDataWhitening(bool_t enable) @@ -1191,8 +1153,6 @@ void PalBbBleEnableDataWhitening(bool_t enable) * * \param enable flag to indicate PRBS15 * - * \return None. - * * Immediately enable or disable continuous PRBS15 bitstream. */ /*************************************************************************************************/ @@ -1237,6 +1197,7 @@ void PalBbBleEnablePrbs15(bool_t enable) /* update the driver state */ driverState = IDLE_STATE; + BB_LED_OFF(); } } @@ -1246,9 +1207,6 @@ void PalBbBleEnablePrbs15(bool_t enable) * * \param descs Array of transmit buffer descriptor. * \param cnt Number of descriptors. - * - * \return None. - * */ /*************************************************************************************************/ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) @@ -1271,12 +1229,12 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) palBbRadioHardStop(); busycount = 0; - while ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) && (busycount < 20)) + while ((NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) && (busycount < 10)) { busycount++; } - if (busycount < 20) + if (busycount < 10) { /* Radio state is cleared now, continue TxData operation. */ break; @@ -1308,14 +1266,24 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) ///////////////////////////////////////////////////////////////////////////////// #if (LL_ENABLE_TESTER == TRUE) + /* set Tx access addresses */ + NRF_RADIO->PREFIX0 = (bbTxAccAddr & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = (bbTxAccAddr & 0x00FFFFFF) << 8; + if (invalidateAccAddrOnceTx) + { + invalidateAccAddrOnceTx = FALSE; + + /* invalidate */ + NRF_RADIO->PREFIX0 = ((bbTxAccAddr ^ 0xFFFFFFFF) & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = ((bbTxAccAddr ^ 0xFFFFFFFF) & 0x00FFFFFF) << 8; + } + uint16_t hdr; BYTES_TO_UINT16(hdr, pBuf); - if ((hdr & bbModifyTxHdrMask) == bbModifyTxHdrValue) - { - /* set Tx access addresses */ - NRF_RADIO->PREFIX0 = (bbTxAccAddr & 0xFF000000) >> 24; - NRF_RADIO->BASE0 = (bbTxAccAddr & 0x00FFFFFF) << 8; + if (bbModifyTxHdrMask && + ((hdr & bbModifyTxHdrMask) == bbModifyTxHdrValue)) + { if (bbTxAccAddrInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if ((bbTxAccAddrInvalidAdjMask & (1 << bbTxAccAddrInvalidStep)) || bbTxAccAddrShiftMask) @@ -1365,9 +1333,13 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) } } } + } - /* set Tx CRC init */ - NRF_RADIO->CRCINIT = bbTxCrcInit; + /* set Tx CRC init */ + NRF_RADIO->CRCINIT = bbTxCrcInit; + if (bbModifyTxHdrMask && + ((hdr & bbModifyTxHdrMask) == bbModifyTxHdrValue)) + { if (bbTxCrcInitInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if (bbTxCrcInitInvalidAdjMask & (1 << bbTxCrcInitInvalidStep)) @@ -1385,10 +1357,28 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) #endif /* calculate start time */ - uint32_t txStart = bbAntennaDueTime - USEC_TO_TICKS(NRF5x_tTXEN_BLE_USECS + NRF5x_PROP_DELAY_TX_USECS); + uint32_t txStart = BB_US_TO_BB_TICKS(bbAntennaDueTimeUsec - (NRF5x_tTXEN_BLE_USECS + NRF5x_PROP_DELAY_TX_USECS)); /* set timer compare CC[0] for time to trigger a transmit */ #if (USE_RTC_BB_CLK) + uint32_t txStartUsec = bbAntennaDueTimeUsec - (NRF5x_tTXEN_BLE_USECS + NRF5x_PROP_DELAY_TX_USECS); + + if (bbAntennaDueTimeUsec < NRF5x_tTXEN_BLE_USECS + NRF5x_PROP_DELAY_TX_USECS) + { + txStartUsec = bbAntennaDueTimeUsec - NRF5x_tTXEN_BLE_USECS - NRF5x_PROP_DELAY_TX_USECS + BB_RTC_MAX_VALUE_US + 1; + } + + txStart = BB_US_TO_BB_TICKS(txStartUsec); + + int16_t dueOffsetUsec = txStartUsec - BB_TICKS_TO_US(txStart); + + bbDueOffsetUsec = dueOffsetUsec > 0 ? dueOffsetUsec : 0; + + if (bbDueOffsetUsec > 31) + { + bbDueOffsetUsec = 31; + } + if (bbDueOffsetUsec == 0) { bbDueOffsetUsec = 1; /* CC[0] can't trigger on 0 */ @@ -1397,7 +1387,7 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) NRF_TIMER0->CC[0] = bbDueOffsetUsec; NRF_TIMER0->EVENTS_COMPARE[0] = 0; WAIT_FOR_WR_BUF_EMPTY(NRF_TIMER0->EVENTS_COMPARE[0]); - palBbSetHfClkStart(txStart); + palBbStartTimer(txStart); #else BB_ASSERT(bbDueOffsetUsec == 0); /* Always 0 with HFCLK. */ NRF_TIMER0->CC[0] = txStart; @@ -1412,8 +1402,15 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk; + uint32_t currentBbTick; + (void)PalBbGetTimestamp(¤tBbTick); + /* see if the due time is in the past (or a very long way, away) */ - if ((txStart - PalBbGetCurrentTime(USE_RTC_BB_CLK)) & 0x80000000) +#if (USE_RTC_BB_CLK) + if ((txStart - currentBbTick) & 0x00800000) /* Check MSB of 24 bit RTC counter. */ +#else + if ((txStart - currentBbTick) & 0x80000000) +#endif { ///////////////////////////////////////////////////////////////////////////////// #ifdef DIAGNOSTICS @@ -1467,8 +1464,6 @@ void PalBbBleTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) * \param descs Transmit data buffer descriptor. * \param cnt Transmit data count. * - * \return None. - * * If possible, the transmit will occur at the TIFS timing. If not possible, the callback status * will indicate this. */ @@ -1491,13 +1486,23 @@ void PalBbBleTxTifsData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) ///////////////////////////////////////////////////////////////////////////////// #if (LL_ENABLE_TESTER == TRUE) + /* set Tx access addresses */ + NRF_RADIO->PREFIX0 = (bbTxAccAddr & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = (bbTxAccAddr & 0x00FFFFFF) << 8; + if (invalidateAccAddrOnceTx) + { + invalidateAccAddrOnceTx = FALSE; + + /* invalidate */ + NRF_RADIO->PREFIX0 = ((bbTxAccAddr ^ 0xFFFFFFFF) & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = ((bbTxAccAddr ^ 0xFFFFFFFF) & 0x00FFFFFF) << 8; + } + uint16_t hdr; BYTES_TO_UINT16(hdr, pBuf); + if ((hdr & bbModifyTxHdrMask) == bbModifyTxHdrValue) { - /* set Tx access addresses */ - NRF_RADIO->PREFIX0 = (bbTxAccAddr & 0xFF000000) >> 24; - NRF_RADIO->BASE0 = (bbTxAccAddr & 0x00FFFFFF) << 8; if (bbTxAccAddrInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if ((bbTxAccAddrInvalidAdjMask & (1 << bbTxAccAddrInvalidStep)) || bbTxAccAddrShiftMask) @@ -1547,9 +1552,12 @@ void PalBbBleTxTifsData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) } } } + } - /* set Tx CRC init */ - NRF_RADIO->CRCINIT = bbTxCrcInit; + /* set Tx CRC init */ + NRF_RADIO->CRCINIT = bbTxCrcInit; + if ((hdr & bbModifyTxHdrMask) == bbModifyTxHdrValue) + { if (bbTxCrcInitInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if (bbTxCrcInitInvalidAdjMask & (1 << bbTxCrcInitInvalidStep)) @@ -1644,14 +1652,28 @@ void PalBbBleTxTifsData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) * * \param pTxBuf - pointer to buffer to transmit * - * \return None. - * * Configuration common to TIFS and non-TIFS transmit. * */ /*===============================================================================================*/ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) { +#if defined(NRF52840_XXAA) + if (bbTxPhy == BB_PHY_BLE_CODED) + { + /* Improve Coded sensitivity for nRF52840 chip. */ + *(volatile uint32_t *)0x4000173C |= 0x80000000; + *(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); + } + + uint32_t plen = ((bbTxPhy != BB_PHY_BLE_1M) ? ((bbTxPhy != BB_PHY_BLE_2M) ? RADIO_PCNF0_PLEN_LongRange : RADIO_PCNF0_PLEN_16bit) \ + : RADIO_PCNF0_PLEN_8bit) << RADIO_PCNF0_PLEN_Pos; +#elif defined(NRF52832_XXAA) + uint32_t plen = ((bbTxPhy == BB_PHY_BLE_2M) ? RADIO_PCNF0_PLEN_16bit : RADIO_PCNF0_PLEN_8bit) << RADIO_PCNF0_PLEN_Pos; +#else + uint32_t plen = 0; +#endif + if (!bbEncryptTxFlag) { /*------------------------------------------------------------------------------ @@ -1662,21 +1684,6 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) * format. This also allows for zero copy as well. * */ -#if defined(NRF52840_XXAA) - if (bbTxPhy == BB_PHY_BLE_CODED) - { - /* Improve Coded sensitivity for nRF52840 chip. */ - *(volatile uint32_t *)0x4000173C |= 0x80000000; - *(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C); - } - - uint32_t plen = ((bbTxPhy != BB_PHY_BLE_1M) ? ((bbTxPhy != BB_PHY_BLE_2M) ? RADIO_PCNF0_PLEN_LongRange : RADIO_PCNF0_PLEN_16bit) \ - : RADIO_PCNF0_PLEN_8bit) << RADIO_PCNF0_PLEN_Pos; -#elif defined(NRF52832_XXAA) - uint32_t plen = ((bbTxPhy == BB_PHY_BLE_2M) ? RADIO_PCNF0_PLEN_16bit : RADIO_PCNF0_PLEN_8bit) << RADIO_PCNF0_PLEN_Pos; -#else - uint32_t plen = 0; -#endif /* configure PCNF0 */ NRF_RADIO->PCNF0 = (((uint32_t)( 1 /* S0 field in bytes */ )) << RADIO_PCNF0_S0LEN_Pos) | @@ -1726,22 +1733,23 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) BB_ASSERT( packetCountSetFlag ); /* packet count was not set */ /* configure PCNF0 */ - NRF_RADIO->PCNF0 = (((uint32_t)( 1 /* S0 field in bytes */ )) << RADIO_PCNF0_S0LEN_Pos) | - (((uint32_t)( 5 /* length field in bits */ )) << RADIO_PCNF0_LFLEN_Pos) | + NRF_RADIO->PCNF0 = (((uint32_t)( 1 /* S0 field in bytes */ )) << RADIO_PCNF0_S0LEN_Pos) | + (((uint32_t)( 8 /* length field in bits */ )) << RADIO_PCNF0_LFLEN_Pos) | + (((uint32_t)( 0 /* S1 field in bits */ )) << RADIO_PCNF0_S1LEN_Pos) | #if defined(NRF52840_XXAA) (((uint32_t)((bbTxPhy == BB_PHY_BLE_CODED) ? 3 : 0 /* TERM field in bits*/ )) << RADIO_PCNF0_TERMLEN_Pos) | (((uint32_t)((bbTxPhy == BB_PHY_BLE_CODED) ? 2 : 0 /* CI field in bits */ )) << RADIO_PCNF0_CILEN_Pos) | (((uint32_t)( 0 /* CRCINC field */ )) << RADIO_PCNF0_CRCINC_Pos) | - (((uint32_t)( 0 /* S1INCL filed */ )) << RADIO_PCNF0_S1INCL_Pos) | + (((uint32_t)( 1 /* S1INCL filed */ )) << RADIO_PCNF0_S1INCL_Pos) | #endif - (((uint32_t)( 3 /* S1 field in bits */ )) << RADIO_PCNF0_S1LEN_Pos); + ((uint32_t)( plen /* preamble field in bits */ )); /* configure PCNF1 */ - NRF_RADIO->PCNF1 = (((uint32_t)( 0 /* maximum packet length */ )) << RADIO_PCNF1_MAXLEN_Pos ) | - (((uint32_t)( 0 /* static packet length */ )) << RADIO_PCNF1_STATLEN_Pos ) | - (((uint32_t)( NORDIC_BASE_ADDR_LEN )) << RADIO_PCNF1_BALEN_Pos ) | - (((uint32_t)( RADIO_PCNF1_ENDIAN_Little )) << RADIO_PCNF1_ENDIAN_Pos ) | - (((uint32_t)( bbRadioPcnf1WhiteEn )) << RADIO_PCNF1_WHITEEN_Pos ); + NRF_RADIO->PCNF1 = (((uint32_t)( 0 /* maximum packet length */ )) << RADIO_PCNF1_MAXLEN_Pos ) | + (((uint32_t)( 0 /* static packet length */ )) << RADIO_PCNF1_STATLEN_Pos ) | + (((uint32_t)( NORDIC_BASE_ADDR_LEN )) << RADIO_PCNF1_BALEN_Pos ) | + (((uint32_t)( RADIO_PCNF1_ENDIAN_Little )) << RADIO_PCNF1_ENDIAN_Pos ) | + (((uint32_t)( bbRadioPcnf1WhiteEn )) << RADIO_PCNF1_WHITEEN_Pos ); /* set packet pointer to the soon-to-be encrypted buffer */ NRF_RADIO->PACKETPTR = (uint32_t)&bbEncryptOutBuf[0]; @@ -1760,6 +1768,41 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) BB_ASSERT(bbEncryptTxBuf[sizeof(bbEncryptTxBuf)-1] == 0xAA); /* buffer overrun from memcpy */ BB_ASSERT(bbEncryptTxBuf[sizeof(bbEncryptTxBuf)-2] == 0xAA); /* buffer overrun from memcpy */ + NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos); + NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos); + + NRF_CCM->CNFPTR = (uint32_t)bbEncryptCcmData; + NRF_CCM->SCRATCHPTR = (uint32_t)bbEncryptScratchBuf; + + NRF_CCM->INPTR = (uint32_t)bbEncryptTxBuf; + NRF_CCM->OUTPTR = (uint32_t)bbEncryptOutBuf; + + uint32_t ccmModeDatarate; + switch (bbTxPhy) + { + default: + case BB_PHY_BLE_1M: + ccmModeDatarate = CCM_MODE_DATARATE_1Mbit << CCM_MODE_DATARATE_Pos; + break; + case BB_PHY_BLE_2M: + ccmModeDatarate = CCM_MODE_DATARATE_2Mbit << CCM_MODE_DATARATE_Pos; + break; +#if defined(NRF52840_XXAA) + case BB_PHY_BLE_CODED: + ccmModeDatarate = ((bbTxPhyOptions == BB_PHY_OPTIONS_BLE_S2) ? CCM_MODE_DATARATE_500Kbps : CCM_MODE_DATARATE_125Kbps) + << CCM_MODE_DATARATE_Pos; + break; +#endif + } + + NRF_CCM->MODE = (CCM_MODE_MODE_Encryption << CCM_MODE_MODE_Pos) | + (ccmModeDatarate) | + (CCM_MODE_LENGTH_Extended << CCM_MODE_LENGTH_Pos); + + NRF_CCM->EVENTS_ENDCRYPT = 0; + NRF_CCM->EVENTS_ENDKSGEN = 0; + NRF_CCM->EVENTS_ERROR = 0; + /* ---------- handle MIC suppression ---------- */ if (bbEncryptTxSuppressMic) { @@ -1767,7 +1810,6 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) bbEncryptOutBuf[1] = 0xFF; /* clear the ENDKSGEN event, aka "key-stream generation complete" event */ - NRF_CCM->EVENTS_ENDKSGEN = 0; WAIT_FOR_WR_BUF_EMPTY(NRF_CCM->EVENTS_ENDKSGEN); /* enable the ENDKSGEN interrupt, this interrupt will revert length to original "MIC-less" length */ @@ -1775,6 +1817,17 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) } /* -------------------------------------------- */ +#if (LL_ENABLE_TESTER) + if ((llTesterCb.pktMic) || (llTesterCb.pktLlId)) + { + /* clear the ENDCRYPT event */ + WAIT_FOR_WR_BUF_EMPTY(NRF_CCM->EVENTS_ENDCRYPT); + + /* enable the ENDCRYPT interrupt, this interrupt will modify the MIC/LLID */ + NRF_CCM->INTENSET = CCM_INTENSET_ENDCRYPT_Msk; + } +#endif + /* set shortcut to start encryption immediately after key generation */ NRF_CCM->SHORTS = CCM_SHORTS_ENDKSGEN_CRYPT_Msk; // TODO - probably just need to set once at initialization ***** @@ -1789,48 +1842,65 @@ static void palBbTxHwRadioConfig(uint8_t * pTxBuf) * * \param None. * - * \return None. - * * This interrupt undoes Nordic's automatic +4 to the length field. This allows transmitting * without the MIC. - * */ /*************************************************************************************************/ void CCM_AAR_IRQHandler(void) { - BB_ASSERT(NRF_CCM->INTENSET == CCM_INTENSET_ENDKSGEN_Msk); /* only keygen complete should be enabled */ + if (bbEncryptTxSuppressMic) + { + BB_ASSERT(NRF_CCM->INTENSET == CCM_INTENSET_ENDKSGEN_Msk); /* only keygen complete should be enabled */ - /* -----------------------------------------------------------------------------* - * ENDKSGEN - Key Generation Complete - * -----------------------------------------------------------------------------*/ - BB_ASSERT(NRF_CCM->EVENTS_ENDKSGEN); /* this event should have been set */ + /* -----------------------------------------------------------------------------* + * ENDKSGEN - Key Generation Complete + * -----------------------------------------------------------------------------*/ + BB_ASSERT(NRF_CCM->EVENTS_ENDKSGEN); /* this event should have been set */ - /* disable this interrupt */ - NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; + /* disable this interrupt */ + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDKSGEN_Msk; - /* - * The key-stream generation has just completed. A shortcut should immediately - * start encryption which populates the output buffer. The second byte of the - * output buffer will be the length. Nordic automatically adds four to account for - * the addition of the MIC. To avoid transmitting the MIC in the "MIC-less" mode, - * this interrupt readjusts the length before it gets transmitted. - */ + /* + * The key-stream generation has just completed. A shortcut should immediately + * start encryption which populates the output buffer. The second byte of the + * output buffer will be the length. Nordic automatically adds four to account for + * the addition of the MIC. To avoid transmitting the MIC in the "MIC-less" mode, + * this interrupt readjusts the length before it gets transmitted. + */ - /* wait for the length field to be populated by the Nordic hardware */ - while(bbEncryptOutBuf[1] == 0xFF) - { - /////////////////////////////////////////////////////////////////////////////// - #ifdef BB_ASSERT_ENABLED - uint8_t busycount = 0; - BB_ASSERT(busycount < 10); /* got stuck */ - busycount++; - #endif - /////////////////////////////////////////////////////////////////////////////// + /* wait for the length field to be populated by the Nordic hardware */ + while (bbEncryptOutBuf[1] == 0xFF) + { + /////////////////////////////////////////////////////////////////////////////// + #ifdef BB_ASSERT_ENABLED + uint8_t busycount = 0; + BB_ASSERT(busycount < 10); /* got stuck */ + busycount++; + #endif + /////////////////////////////////////////////////////////////////////////////// + } + + /* overwrite with the length field with the original length, that does not include the MIC */ + BB_ASSERT(bbTxLen == (bbEncryptOutBuf[1] - 4)); /* the populated length should be exactly +4 */ + bbEncryptOutBuf[1] = bbTxLen; } - /* overwrite with the length field with the original length, that does not include the MIC */ - BB_ASSERT(bbTxLen == (bbEncryptOutBuf[1] - 4)); /* the populated length should be exactly +4 */ - bbEncryptOutBuf[1] = bbTxLen; +#if (LL_ENABLE_TESTER) + if ((llTesterCb.pktMic) || (llTesterCb.pktLlId)) + { + BB_ASSERT(NRF_CCM->EVENTS_ENDCRYPT); /* this event should have been set */ + + /* disable this interrupt */ + NRF_CCM->INTENCLR = CCM_INTENCLR_ENDCRYPT_Msk; + + bbEncryptOutBuf[0] ^= llTesterCb.pktLlId & 0x03; + + bbEncryptOutBuf[bbTxLen] ^= (llTesterCb.pktMic >> 0) & 0xFF; + bbEncryptOutBuf[bbTxLen+1] ^= (llTesterCb.pktMic >> 8) & 0xFF; + bbEncryptOutBuf[bbTxLen+2] ^= (llTesterCb.pktMic >> 16) & 0xFF; + bbEncryptOutBuf[bbTxLen+3] ^= (llTesterCb.pktMic >> 24) & 0xFF; + } +#endif } /*************************************************************************************************/ @@ -1840,8 +1910,6 @@ void CCM_AAR_IRQHandler(void) * \param pBuf Transmit data buffer. * \param len Length of data buffer. * - * \return None. - * * The receiver is kept on for the amount of time previously configured by function call. */ /*************************************************************************************************/ @@ -1866,6 +1934,15 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len) /* set Rx access addresses */ NRF_RADIO->PREFIX0 = (bbRxAccAddr & 0xFF000000) >> 24; NRF_RADIO->BASE0 = (bbRxAccAddr & 0x00FFFFFF) << 8; + if (invalidateAccAddrOnceRx) + { + invalidateAccAddrOnceRx = FALSE; + + /* invalidate */ + NRF_RADIO->PREFIX0 = ((bbRxAccAddr ^ 0xFFFFFFFF) & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = ((bbRxAccAddr ^ 0xFFFFFFFF) & 0x00FFFFFF) << 8; + } + if (bbRxAccAddrInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if (bbRxAccAddrInvalidAdjMask & (1 << bbRxAccAddrInvalidStep)) @@ -1906,10 +1983,28 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len) palBbRadioHardStop(); /* calculate start time */ - uint32_t rxStart = bbAntennaDueTime - USEC_TO_TICKS(NRF5x_tRXEN_BLE_USECS + NRF5x_PROP_DELAY_RX_USECS); + uint32_t rxStart = BB_US_TO_BB_TICKS(bbAntennaDueTimeUsec - (NRF5x_tRXEN_BLE_USECS + NRF5x_PROP_DELAY_RX_USECS)); /* set timer compare CC[0] for time to trigger a transmit */ #if (USE_RTC_BB_CLK) + uint32_t rxStartUsec = bbAntennaDueTimeUsec - (NRF5x_tRXEN_BLE_USECS + NRF5x_PROP_DELAY_RX_USECS); + + if (bbAntennaDueTimeUsec < NRF5x_tRXEN_BLE_USECS + NRF5x_PROP_DELAY_RX_USECS) + { + rxStartUsec = bbAntennaDueTimeUsec - NRF5x_tRXEN_BLE_USECS - NRF5x_PROP_DELAY_RX_USECS + BB_RTC_MAX_VALUE_US + 1; + } + + rxStart = BB_US_TO_BB_TICKS(rxStartUsec); + + int16_t dueOffsetUsec = rxStartUsec - BB_TICKS_TO_US(rxStart); + + bbDueOffsetUsec = dueOffsetUsec > 0 ? dueOffsetUsec : 0; + + if (bbDueOffsetUsec > 31) + { + bbDueOffsetUsec = 31; + } + if (bbDueOffsetUsec == 0) { bbDueOffsetUsec = 1; /* CC[0] can't trigger on 0 */ @@ -1918,7 +2013,7 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len) NRF_TIMER0->CC[0] = bbDueOffsetUsec; NRF_TIMER0->EVENTS_COMPARE[0] = 0; WAIT_FOR_WR_BUF_EMPTY(NRF_TIMER0->EVENTS_COMPARE[0]); - palBbSetHfClkStart(rxStart - 1); /* Subtract 1 for receive uncertainty due to rounding. */ + palBbStartTimer(rxStart - 1); /* Subtract 1 for receive uncertainty due to rounding. */ #else BB_ASSERT(bbDueOffsetUsec == 0); /* Always 0 with HFCLK. */ NRF_TIMER0->CC[0] = rxStart; @@ -1982,8 +2077,15 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len) RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk; - /* see if the requested due is in the past (or a very long way, away) */ - if ((rxStart - PalBbGetCurrentTime(USE_RTC_BB_CLK)) & 0x80000000) + uint32_t currentBbTick; + (void)PalBbGetTimestamp(¤tBbTick); + + /* see if the due time is in the past (or a very long way, away) */ +#if (USE_RTC_BB_CLK) + if ((rxStart - currentBbTick) & 0x00800000) /* Check MSB of 24 bit RTC counter. */ +#else + if ((rxStart - currentBbTick) & 0x80000000) +#endif { ///////////////////////////////////////////////////////////////////////////////// #ifdef DIAGNOSTICS @@ -2035,8 +2137,6 @@ void PalBbBleRxData(uint8_t *pBuf, uint16_t len) * \param pBuf Receive data buffer. * \param len Length of data buffer. * - * \return None. - * * The receiver is left on for the minimum amount of time to recognize a receive. * * If possible, the receive will occur on the TIFS timing. If not possible, the callback status @@ -2064,6 +2164,15 @@ void PalBbBleRxTifsData(uint8_t *pBuf, uint16_t len) /* set Rx access addresses */ NRF_RADIO->PREFIX0 = (bbRxAccAddr & 0xFF000000) >> 24; NRF_RADIO->BASE0 = (bbRxAccAddr & 0x00FFFFFF) << 8; + if (invalidateAccAddrOnceRx) + { + invalidateAccAddrOnceRx = FALSE; + + /* invalidate */ + NRF_RADIO->PREFIX0 = ((bbRxAccAddr ^ 0xFFFFFFFF) & 0xFF000000) >> 24; + NRF_RADIO->BASE0 = ((bbRxAccAddr ^ 0xFFFFFFFF) & 0x00FFFFFF) << 8; + } + if (bbRxAccAddrInvalidChanMask & (UINT64_C(1) << bbChanIndex)) { if (bbRxAccAddrInvalidAdjMask & (1 << bbRxAccAddrInvalidStep)) @@ -2171,8 +2280,6 @@ void PalBbBleRxTifsData(uint8_t *pBuf, uint16_t len) * \param pRxBuf - pointer where receive bytes get written * \param len - maximum length for receive, i.e. size of the allocated receive buffer * - * \return None. - * * Configuration common to TIFS and non-TIFS transmit. * */ @@ -2231,8 +2338,6 @@ static void palBbRxHwRadioConfig(uint8_t * pRxBuf, uint16_t len) * * \param None. * - * \return None. - * * This is the "RX Timeout" interrupt. No other functionality is shared on the TIMER0 interrupt. * If the receive operation has not gotten started, it is cancelled. * @@ -2240,8 +2345,6 @@ static void palBbRxHwRadioConfig(uint8_t * pRxBuf, uint16_t len) /*************************************************************************************************/ void BbBleDrvTimerIRQHandler(void) { - DIAG_PIN_SET( TIMER0_INT_PIN ); - BB_ASSERT(NRF_TIMER0->INTENSET == TIMER_INTENSET_COMPARE1_Msk); /* only RX timeout should be enabled */ /* -----------------------------------------------------------------------------* @@ -2265,8 +2368,6 @@ void BbBleDrvTimerIRQHandler(void) /* send notification of timeout */ bbRxCallback(BB_STATUS_RX_TIMEOUT, 0, 0, 0, 0); } - - DIAG_PIN_CLEAR( TIMER0_INT_PIN ); } /*************************************************************************************************/ @@ -2275,8 +2376,6 @@ void BbBleDrvTimerIRQHandler(void) * * \param None. * - * \return None. - * * This the radio interrupt service routine. It is at the heart of the baseband driver * design. It handles the following interrupts: * @@ -2296,8 +2395,6 @@ void BbBleDrvTimerIRQHandler(void) /*************************************************************************************************/ void BbBleDrvRadioIRQHandler(void) { - DIAG_PIN_SET( RADIO_INT_PIN ); - /* -----------------------------------------------------------------------------* * READY - "TIFS Expired" * -----------------------------------------------------------------------------*/ @@ -2320,7 +2417,7 @@ void BbBleDrvRadioIRQHandler(void) if ((driverState == TX_STATE) || (tifsState == TIFS_TX_RAMPUP)) { - DIAG_PIN_SET( TX_PIN ); + BB_LED_TX_ON(); BB_ASSERT(NRF_RADIO->STATE == RADIO_STATE_STATE_Tx); } @@ -2328,7 +2425,7 @@ void BbBleDrvRadioIRQHandler(void) if ((driverState == RX_STATE) || (tifsState == TIFS_RX_RAMPUP)) { BB_ASSERT(NRF_RADIO->STATE == RADIO_STATE_STATE_Rx); - DIAG_PIN_SET( RX_PIN ); + BB_LED_RX_ON(); /* clear the ADDRESS event, it will indicate if an RX timeout is possible */ NRF_RADIO->EVENTS_ADDRESS = 0; @@ -2378,7 +2475,8 @@ void BbBleDrvRadioIRQHandler(void) /* - - - - - - - - - - - - - - - - - - - - - - - - - * * TX, set up for TIFS-RX * - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (driverState == TX_STATE) + if ((bbOpParam.ifsMode == PAL_BB_IFS_MODE_TOGGLE_TIFS) && + (driverState == TX_STATE)) { uint32_t antennaTimeTxPktEnd; uint32_t crcTime; @@ -2454,8 +2552,6 @@ void BbBleDrvRadioIRQHandler(void) - TICKS_PER_USEC * NRF5x_tRXEN_BLE_USECS /* subtract time it takes to ramp-up for receive */ - TICKS_PER_USEC * MAX_TIFS_DEVIATION_USECS; /* subtract allowed deviation */ - - /* configure and enable PPI trigger for RXEN, happens on next timer COMPARE[0] just configured above */ NRF_PPI->CH[14].TEP = (uint32_t) &NRF_RADIO->TASKS_RXEN; /* configure task */ NRF_PPI->CHENSET = PPI_CHENSET_CH14_Msk; /* enable channel */ @@ -2489,7 +2585,8 @@ void BbBleDrvRadioIRQHandler(void) /* - - - - - - - - - - - - - - - - - - - - - - - - - * * RX, set up for TIFS-TX * - - - - - - - - - - - - - - - - - - - - - - - - - */ - else + else if ((bbOpParam.ifsMode == PAL_BB_IFS_MODE_TOGGLE_TIFS) && + (driverState == RX_STATE)) { uint32_t antennaTimeRxPktEnd; uint32_t crcTime; @@ -2576,6 +2673,105 @@ void BbBleDrvRadioIRQHandler(void) tifsState = TIFS_TX_RAMPUP; } + /* - - - - - - - - - - - - - - - - - - - - - - - - - * + * RX, set up for TIFS-RX + * - - - - - - - - - - - - - - - - - - - - - - - - - */ + else if ((bbOpParam.ifsMode == PAL_BB_IFS_MODE_SAME_ABS) && + (driverState == RX_STATE)) + { + uint32_t preambleTime; + uint32_t accessAddrTime; + int32_t correction; + + /* calculate time to receive preamble and access address */ + switch(bbRxPhy) + { + case BB_PHY_BLE_1M: + preambleTime = LL_BLE_US_PER_BYTE_1M * LL_PREAMBLE_LEN_1M; + accessAddrTime = LL_BLE_US_PER_BYTE_1M * LL_AA_LEN; + correction = 4; + break; + case BB_PHY_BLE_2M: + preambleTime = LL_BLE_US_PER_BYTE_2M * LL_PREAMBLE_LEN_2M; + accessAddrTime = LL_BLE_US_PER_BYTE_2M * LL_AA_LEN; + correction = 20; + break; +#if defined(NRF52840_XXAA) + case BB_PHY_BLE_CODED: + preambleTime = LL_BLE_US_PER_BIT_CODED_S8 * LL_PREAMBLE_LEN_CODED_BITS; + accessAddrTime = LL_BLE_US_PER_BYTE_CODED_S8 * LL_AA_LEN; + correction = 110; + break; +#endif + default: + preambleTime = LL_BLE_US_PER_BYTE_1M * LL_PREAMBLE_LEN_1M; + accessAddrTime = LL_BLE_US_PER_BYTE_1M * LL_AA_LEN; + correction = 4; + } + + NRF_TIMER0->CC[0] = BB_US_TO_BB_TICKS(bbOpParam.ifsTime - (NRF5x_tRXEN_BLE_USECS + NRF5x_PROP_DELAY_RX_USECS)); + + /* configure and enable PPI trigger for RXEN, happens on next timer COMPARE[0] just configured above */ + NRF_PPI->CH[14].TEP = (uint32_t) &NRF_RADIO->TASKS_RXEN; /* configure task */ + NRF_PPI->CHENSET = PPI_CHENSET_CH14_Msk; /* enable channel */ + + /* set timer compare CC[1] for RX timeout (allow time to recognize address, and account for propagation delay) */ + NRF_TIMER0->CC[1] = NRF_TIMER0->CC[0] + + TICKS_PER_USEC * (30 /* TODO Resolve total deviation allowed */ + + preambleTime + + accessAddrTime + + NRF5x_PROP_DELAY_RX_USECS + + NRF5x_tRXEN_BLE_USECS + + correction); + + /* + * NOTE: In the case of an RX timeout, the above compare will trigger an interrupt. + * This interrupt requires time to execute. This delay extends the time the radio + * is active. The effective timeout period is longer than computed above. + * + * This effective timeout period can be reduced using the trim value. + * This would be useful for power savings. But be warned!! Great care + * is required as this involves timing the speed of code execution. + * Any adjustment must be made with debug code disabled. + */ + + /* clear RX timeout compare event, but do not enable interrupt, that happens in radio isr */ + NRF_TIMER0->EVENTS_COMPARE[1] = 0; + WAIT_FOR_WR_BUF_EMPTY(NRF_TIMER0->EVENTS_COMPARE[1]); + + /* update channel parameters */ + if (bbOpParam.pIfsChan) + { + palBbBleSetChannelParam(bbOpParam.pIfsChan); + } + + /* a TX is completing, the radio will soon be ramping up for possible TIFS RX */ + tifsState = TIFS_RX_RAMPUP; + } + + /* - - - - - - - - - - - - - - - - - - - - - - - - - * + * TX, set up for TIFS-TX + * - - - - - - - - - - - - - - - - - - - - - - - - - */ + else if ((bbOpParam.ifsMode == PAL_BB_IFS_MODE_SAME_ABS) && + (driverState == TX_STATE)) + { + /* calculate start time */ + NRF_TIMER0->CC[0] = BB_US_TO_BB_TICKS(bbOpParam.ifsTime - (NRF5x_tTXEN_BLE_USECS + NRF5x_PROP_DELAY_TX_USECS)); + + /* configure and enable PPI trigger for TXEN, happens on next timer COMPARE[0] */ + NRF_PPI->CH[14].TEP = (uint32_t) &NRF_RADIO->TASKS_TXEN; /* configure task */ + NRF_PPI->CHENSET = PPI_CHENSET_CH14_Msk; /* enable channel */ + + /* update channel parameters */ + if (bbOpParam.pIfsChan) + { + palBbBleSetChannelParam(bbOpParam.pIfsChan); + } + + /* a TX is completing, the radio will soon be ramping up for possible TIFS RX */ + tifsState = TIFS_TX_RAMPUP; + } + /* ------------------------------------------------------------------------------ * Check to see if TIFS window already missed. This would happen if * interrupts were suppressed for a long time. @@ -2617,8 +2813,8 @@ void BbBleDrvRadioIRQHandler(void) WAIT_FOR_WR_BUF_EMPTY(NRF_RADIO->EVENTS_END); /* clear diagnostics pins */ - DIAG_PIN_CLEAR( TX_PIN ); - DIAG_PIN_CLEAR( RX_PIN ); + BB_LED_TX_OFF(); + BB_LED_RX_OFF(); /* - - - - - - - - - - - - - - - - - - - - - - - - - * * TX Complete @@ -2627,6 +2823,7 @@ void BbBleDrvRadioIRQHandler(void) { /* update driver state, *before* callback */ driverState = IDLE_STATE; + BB_LED_OFF(); /* run callback function */ palBbRestoreTrl(); @@ -2639,6 +2836,7 @@ void BbBleDrvRadioIRQHandler(void) else if (driverState == RX_STATE) { uint32_t timestamp; + uint32_t timestampUsesc; int8_t rssi; uint8_t pduLen; @@ -2704,21 +2902,30 @@ void BbBleDrvRadioIRQHandler(void) pduLen )); /* PDU payload */ } + #if (USE_RTC_BB_CLK) - /* reduce timestamp to BB clock units add RTC clock offset */ - timestamp = USEC_TO_TICKS(timestamp) + bbEventStartTime; + /* RTC event start time plus timestamp from HFCLK timer. */ + timestampUsesc = BB_TICKS_TO_US(bbEventStartTime) + bbDueOffsetUsec + TICKS_TO_USEC(timestamp); + /* Handle wraparound. */ + if (timestampUsesc > BB_RTC_MAX_VALUE_US) + { + timestampUsesc -= BB_RTC_MAX_VALUE_US; + } +#else + timestampUsesc = BB_TICKS_TO_US(timestamp); #endif /* compute RSSI value at antenna end */ rssi = (int8_t)(-(NRF_RADIO->RSSISAMPLE & 0x7F)) - PalRadioGetRxRfPathComp(); /* update driver state, *before* callback */ driverState = IDLE_STATE; + BB_LED_OFF(); /* Follow Rx PHY options */ bbTxPhyOptions = bbRxPhyOptions; /* Overwrite with TIFS preference */ - if(tifsTxPhyOptions) + if (tifsTxPhyOptions) { bbTxPhyOptions = tifsTxPhyOptions; } @@ -2727,12 +2934,12 @@ void BbBleDrvRadioIRQHandler(void) if ((NRF_RADIO->CRCSTATUS & RADIO_CRCSTATUS_CRCSTATUS_Msk) == RADIO_CRCSTATUS_CRCSTATUS_CRCError) { /* CRC error - run the callback function */ - bbRxCallback(BB_STATUS_CRC_FAILED, rssi, NRF_RADIO->RXCRC, timestamp, bbRxPhyOptions); + bbRxCallback(BB_STATUS_CRC_FAILED, rssi, NRF_RADIO->RXCRC, timestampUsesc, bbRxPhyOptions); } else { /* Success! - run the callback function */ - bbRxCallback(BB_STATUS_SUCCESS, rssi, NRF_RADIO->RXCRC, timestamp, bbRxPhyOptions); + bbRxCallback(BB_STATUS_SUCCESS, rssi, NRF_RADIO->RXCRC, timestampUsesc, bbRxPhyOptions); } } @@ -2757,16 +2964,12 @@ void BbBleDrvRadioIRQHandler(void) { BB_ASSERT(0); } - - DIAG_PIN_CLEAR( RADIO_INT_PIN ); } /*************************************************************************************************/ /*! * \brief Cancel TIFS timer. * - * \return None. - * * This stops any active TIFS timer operation. This routine is always called in the callback * (i.e. ISR) context. */ @@ -2784,8 +2987,6 @@ void PalBbBleCancelTifs(void) /*! * \brief Cancel a pending transmit or receive. * - * \return None. - * * This stops any active radio operation. This routine is never called in the callback * (i.e. ISR) context. */ @@ -2840,8 +3041,6 @@ void PalBbBleCancelData(void) * * \param None. * - * \return None. - * * Immediately stops the radio. All radio interrupts are cancelled. The radio is put into * the disabled state. This function does not return until the disabled state is verified. * @@ -2862,20 +3061,18 @@ static void palBbRadioHardStop(void) NRF_PPI->CHENCLR = PPI_CHENCLR_CH14_Msk; /* COMPARE[0] -> TXEN/RXEN */ /* disable HFCLK */ -#if (USE_RTC_BB_CLK) - NRF_TIMER0->TASKS_STOP = 1; - NRF_TIMER0->TASKS_CLEAR = 1; -#endif + PalBbBleLowPower(); /* update TIFS state */ tifsState = TIFS_NULL; /* update driver state */ driverState = IDLE_STATE; + BB_LED_OFF(); /* clear diagnostics pins */ - DIAG_PIN_CLEAR( TX_PIN ); - DIAG_PIN_CLEAR( RX_PIN ); + BB_LED_TX_OFF(); + BB_LED_RX_OFF(); /* wait for radio to complete shutdown */ /////////////////////////////////////////////////////////////////////////////// @@ -2922,7 +3119,6 @@ static void palBbRadioHardStop(void) * \param cnt Number of descriptors. * * \return Pointer to transmit data. - * */ /*************************************************************************************************/ static uint8_t *palBbGetTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) @@ -2982,8 +3178,6 @@ static uint8_t *palBbGetTxData(PalBbBleTxBufDesc_t descs[], uint8_t cnt) /*! * \brief Restore trailer data. * - * \return None. - * */ /*************************************************************************************************/ static void palBbRestoreTrl(void) @@ -3003,8 +3197,6 @@ static void palBbRestoreTrl(void) * * \param status status as reported via callback * - * \return None. - * * For diagnostics, this function is used to intercept passing control to the configured * callback function. It is used to record diagnostic information. * @@ -3056,8 +3248,6 @@ static void DiagFauxTxCallback(uint8_t status) * * \param status status as reported via callback * - * \return None. - * * For diagnostics, this function is used to intercept passing control to the configured * callback function. It is used to record diagnostic information. * diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble_rf.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble_rf.c index 0dfc6f5907d..4669be5e46a 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble_rf.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_bb_ble_rf.c @@ -5,14 +5,15 @@ * \brief BLE RF path compensation implementation file. * * Copyright (c) 2016-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,7 +22,7 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_types.h" +#include "pal_types.h" /************************************************************************************************** Macros @@ -45,18 +46,18 @@ #if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) /* \brief Minimum Tx power level (expressed in 1dBm units). */ -static const int16_t bbBleMinTxPwr = -40; /* -40dBm */ +static const int8_t bbBleMinTxPwr = -40; /* -40dBm */ #else /* \brief Minimum Tx power level (expressed in 1dBm units). */ -static const int16_t bbBleMinTxPwr = -30; /* -30dBm */ +static const int8_t bbBleMinTxPwr = -30; /* -30dBm */ #endif #if defined(NRF52840_XXAA) /* \brief Maximum Tx power level (expressed in 1dBm units). */ -static const int16_t bbBleMaxTxPwr = 9; /* +9dBm */ +static const int8_t bbBleMaxTxPwr = 9; /* +9dBm */ #else /* \brief Maximum Tx power level (expressed in 1dBm units). */ -static const int16_t bbBleMaxTxPwr = 4; /* +4dBm */ +static const int8_t bbBleMaxTxPwr = 4; /* +4dBm */ #endif /************************************************************************************************** @@ -69,20 +70,6 @@ int16_t bbBleTxPathComp = -1280; /*! \brief Current Rx path compensation value. */ int16_t bbBleRxPathComp = -1280; -/*************************************************************************************************/ -/*! - * \brief Get transmit RF path compensation. - * - * \return Transmit RF path compensation (in 1-dBm units). - */ -/*************************************************************************************************/ -int8_t palBbBleRfGetTxRfPathComp(void) -{ - uint16_t pathCompUnsigned = (uint16_t)(bbBleTxPathComp - BB_BLE_MIN_PATH_COMP); - - return (int16_t)BB_BLE_MATH_DIV_10(pathCompUnsigned) + BB_BLE_MIN_PATH_COMP_DBM; -} - /*************************************************************************************************/ /*! * \brief Get receive RF path compensation. @@ -92,7 +79,7 @@ int8_t palBbBleRfGetTxRfPathComp(void) /*************************************************************************************************/ int8_t PalRadioGetRxRfPathComp(void) { - uint16_t pathCompUnsigned = (uint16_t)(bbBleRxPathComp - BB_BLE_MIN_PATH_COMP); + uint16_t pathCompUnsigned = (uint16_t)(bbBleTxPathComp - BB_BLE_MIN_PATH_COMP); return (int16_t)BB_BLE_MATH_DIV_10(pathCompUnsigned) + BB_BLE_MIN_PATH_COMP_DBM; } @@ -100,8 +87,6 @@ int8_t PalRadioGetRxRfPathComp(void) /*************************************************************************************************/ /*! * \brief Initialize RF path compensation. - * - * \return None. */ /*************************************************************************************************/ void PalRadioInitPathComp(void) @@ -116,8 +101,6 @@ void PalRadioInitPathComp(void) * * \param pMinTxPwr Return buffer for minimum transmit power (expressed in 1dBm units). * \param pMaxTxPwr Return buffer for maximum transmit power (expressed in 1dBm units). - * - * \return None. */ /*************************************************************************************************/ void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr) @@ -132,8 +115,6 @@ void PalRadioGetSupTxPower(int8_t *pMinTxPwr, int8_t *pMaxTxPwr) * * \param pTxPathComp Return buffer for RF transmit path compensation value (expressed in 0.1dBm units). * \param pRxPathComp Return buffer for RF receive path compensation value (expressed in 0.1dBm units). - * - * \return None. */ /*************************************************************************************************/ void PalRadioReadRfPathComp(int16_t *pTxPathComp, int16_t *pRxPathComp) @@ -214,8 +195,109 @@ int8_t PalRadioGetActualTxPower(int8_t txPwr, bool_t compFlag) if (compFlag) { - txPwr += palBbBleRfGetTxRfPathComp(); + txPwr += PalRadioGetRxRfPathComp(); } return txPwr; } + +/*************************************************************************************************/ +/*! + * \brief Request an increase in power. + + * \param reqPwr Requested Power. + * \param delta Delta + * + * \return TxPower to be set + * + * If increasing power: the controller will increase one step if possible. + * If decreasing power: the controller will only decrease to the ceiling step. + */ +/*************************************************************************************************/ +int8_t PalRadioIncreasePower(int8_t reqPwr, int8_t delta) +{ + /* An increase in power. The controller will always increase one step if possible. */ + if (delta > 0) + { +#if defined(NRF52840_XXAA) + if (reqPwr > 8) { reqPwr = 9; } + else if (reqPwr > 7) { reqPwr = 8; } + else if (reqPwr > 6) { reqPwr = 7; } + else if (reqPwr > 5) { reqPwr = 6; } + else if (reqPwr > 4) { reqPwr = 5; } + else if (reqPwr > 3) { reqPwr = 4; } + else if (reqPwr > 2) { reqPwr = 3; } + else if (reqPwr > 0) { reqPwr = 2; } + else if (reqPwr > -4) { reqPwr = 0; } + else if (reqPwr > -8) { reqPwr = -4; } + else if (reqPwr > -12) { reqPwr = -8; } + else if (reqPwr > -16) { reqPwr = -12; } + else if (reqPwr > -20) { reqPwr = -16; } + else { reqPwr = -20; } +#elif defined(NRF52832_XXAA) + if (reqPwr > 3) { reqPwr = 4; } + else if (reqPwr > 2) { reqPwr = 3; } + else if (reqPwr > 0) { reqPwr = 2; } + else if (reqPwr > -4) { reqPwr = 0; } + else if (reqPwr > -8) { reqPwr = -4; } + else if (reqPwr > -12) { reqPwr = -8; } + else if (reqPwr > -16) { reqPwr = -12; } + else if (reqPwr > -20) { reqPwr = -16; } + else { reqPwr = -20; } +#else + if (reqPwr > 0) { reqPwr = 4; } + else if (reqPwr > -4) { reqPwr = 0; } + else if (reqPwr > -8) { reqPwr = -4; } + else if (reqPwr > -12) { reqPwr = -8; } + else if (reqPwr > -16) { reqPwr = -12; } + else if (reqPwr > -20) { reqPwr = -16; } + else { reqPwr = -20; } +#endif + } + /* A decrease in power. The controller will decrease to higher step if reqPwer is inbetween two steps. */ + else if (delta < 0) + { +#if defined(NRF52840_XXAA) + if (reqPwr <= -40) { reqPwr = -40; } + else if (reqPwr <= -20) { reqPwr = -20; } + else if (reqPwr <= -16) { reqPwr = -16; } + else if (reqPwr <= -12) { reqPwr = -12; } + else if (reqPwr <= -8) { reqPwr = -8; } + else if (reqPwr <= -4) { reqPwr = -4; } + else if (reqPwr <= 0) { reqPwr = 0; } + else if (reqPwr <= 2) { reqPwr = 2; } + else if (reqPwr <= 3) { reqPwr = 3; } + else if (reqPwr <= 4) { reqPwr = 4; } + else if (reqPwr <= 5) { reqPwr = 5; } + else if (reqPwr <= 6) { reqPwr = 6; } + else if (reqPwr <= 7) { reqPwr = 7; } + else if (reqPwr <= 8) { reqPwr = 8; } + else { reqPwr = 9; } +#elif defined(NRF52832_XXAA) + if (reqPwr <= -40) { reqPwr = -40; } + else if (reqPwr <= -20) {reqPwr = -20; } + else if (reqPwr <= -16) {reqPwr = -16; } + else if (reqPwr <= -12) {reqPwr = -12; } + else if (reqPwr <= -8) {reqPwr = -8; } + else if (reqPwr <= -4) {reqPwr = -4; } + else if (reqPwr <= 0) {reqPwr = 0; } + else if (reqPwr <= 3) {reqPwr = 3; } + else {reqPwr = 4; } +#else + if (reqPwr <= -30) {reqPwr = -30; } + else if (reqPwr <= -20) {reqPwr = -20; } + else if (reqPwr <= -16) {reqPwr = -16; } + else if (reqPwr <= -12) {reqPwr = -12; } + else if (reqPwr <= -8) {reqPwr = -8; } + else if (reqPwr <= -4) {reqPwr = -4; } + else if (reqPwr <= 0) {reqPwr = 0; } + else {reqPwr = 4; } +#endif + } + else + { + /* No change. */ + } + + return reqPwr; +} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_cfg.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_cfg.c index f03c5e4c74d..ecbb81dbd96 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_cfg.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_cfg.c @@ -5,14 +5,15 @@ * \brief System configuration definition. * * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,29 +22,9 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_cfg.h" +#include "pal_cfg.h" #include "nrf.h" -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#ifndef LL_MAX_CIG -#define LL_MAX_CIG 2 /*!< Absolute maximum number of connected isochronous groups. */ -#endif - -#ifndef LL_MAX_CIS -#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */ -#endif - -#ifndef LL_MAX_ADV_DATA_LEN -#define LL_MAX_ADV_DATA_LEN 1650 /*!< Maximum advertising data length. */ -#endif - -#ifndef LL_MAX_ADV_SETS -#define LL_MAX_ADV_SETS 6 /*!< Absolute maximum number of advertising sets. */ -#endif - /************************************************************************************************** Type Definitions **************************************************************************************************/ @@ -69,15 +50,19 @@ typedef struct int8_t defTxPwrLvl; /*!< Default Tx power level for connections. */ uint8_t ceJitterUsec; /*!< Allowable CE jitter on a slave (account for master's sleep clock resolution). */ /* ISO */ - uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */ - uint8_t numIsoRxBuf; /*!< Default number of ISO receive buffers. */ - uint16_t maxIsoBufLen; /*!< Maximum ISO buffer size between host and controller. */ - uint16_t maxIsoPduLen; /*!< Maximum ISO PDU size between controllers. */ + uint8_t numIsoTxBuf; /*!< Default number of ISO transmit buffers. */ + uint8_t numIsoRxBuf; /*!< Default number of ISO receive buffers. */ + uint16_t maxIsoSduLen; /*!< Maximum ISO buffer size between host and controller. */ + uint16_t maxIsoPduLen; /*!< Maximum ISO PDU size between controllers. */ /* CIS */ - uint8_t maxCig; /*!< Maximum number of CIG. */ - uint8_t maxCis; /*!< Maximum number of CIS. */ - uint16_t subEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */ + uint8_t maxCig; /*!< Maximum number of CIG. */ + uint8_t maxCis; /*!< Maximum number of CIS, it is shared by the CIGs. */ + uint16_t cisSubEvtSpaceDelay; /*!< Subevent spacing above T_MSS. */ + + /* BIS*/ + uint8_t maxBig; /*!< Maximum number of BIG. */ + uint8_t maxBis; /*!< Maximum number of BIS. */ /* DTM */ uint16_t dtmRxSyncMs; /*!< DTM Rx synchronization window in milliseconds. */ } PalCfgLl_t; @@ -88,7 +73,7 @@ typedef struct /*! \brief convert uint32_t to little endian byte stream, incrementing four bytes. */ #define PAL_UINT32_TO_BSTREAM(p, n) {*(p)++ = (uint8_t)(n); *(p)++ = (uint8_t)((n) >> 8); \ - *(p)++ = (uint8_t)((n) >> 16); *(p)++ = (uint8_t)((n) >> 24);} + *(p)++ = (uint8_t)((n) >> 16); *(p)++ = (uint8_t)((n) >> 24);} /************************************************************************************************** Functions @@ -102,14 +87,12 @@ typedef struct * \param phyCodedSup Coded PHY supported. * \param stableModIdxTxSup Tx stable modulation index supported. * \param stableModIdxRxSup Rx stable modulation index supported. - * - * \return None. */ /*************************************************************************************************/ void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup, - uint8_t *pStableModIdxTxSup, uint8_t *pStableModIdxRxSup) + uint8_t *pStableModIdxTxSup, uint8_t *pStableModIdxRxSup) { -#if defined(NRF52840_XXAA) +#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) *pPhy2mSup = TRUE; *pPhyCodedSup = TRUE; #else @@ -125,42 +108,55 @@ void palCfgGetBlePhyFeatures(uint8_t *pPhy2mSup, uint8_t *pPhyCodedSup, * \brief Load LL advertising configuration. * * \param pConfig Return configuration values. - * - * \return None. */ /*************************************************************************************************/ void palCfgLoadLlParams(uint8_t *pConfig) { PalCfgLl_t *pCfg = (PalCfgLl_t *)pConfig; - #if !defined(NRF52840_XXAA) - const uint16_t advDataLen = 512; - const uint16_t connDataLen = 256; - const uint16_t numTxBufs = 8; - #else - const uint16_t advDataLen = LL_MAX_ADV_DATA_LEN; - const uint16_t connDataLen = 512; - const uint16_t numTxBufs = 16; - #endif +#if defined(BOARD_NRF6832) + const uint16_t maxAdvSets = 1; + const uint16_t advDataLen = 256; + const uint16_t aclDataLen = 256; + const uint16_t maxConn = 1; + const uint16_t maxGroup = 1; + const uint16_t maxStream = 2; +#elif !defined(NRF52840_XXAA) + const uint16_t maxAdvSets = 1; + const uint16_t advDataLen = 512; + const uint16_t aclDataLen = 512; + const uint16_t maxConn = 1; + const uint16_t maxGroup = 1; + const uint16_t maxStream = 2; +#else /* Default */ + const uint16_t maxAdvSets = 6; + const uint16_t advDataLen = 1650; + const uint16_t aclDataLen = 512; + const uint16_t maxConn = 4; + const uint16_t maxGroup = 2; + const uint16_t maxStream = 6; +#endif - pCfg->maxAdvSets = LL_MAX_ADV_SETS; - pCfg->maxAdvReports = 16; + pCfg->maxAdvSets = maxAdvSets; + pCfg->maxAdvReports = 8; pCfg->maxExtAdvDataLen = advDataLen; /* pCfg->defExtAdvDataFragLen */ /* Use default. */ pCfg->auxDelayUsec = 0; pCfg->maxScanReqRcvdEvt = 4; pCfg->maxExtScanDataLen = advDataLen; - pCfg->maxConn = 4; - pCfg->maxAclLen = connDataLen; - pCfg->numTxBufs = numTxBufs; + pCfg->maxConn = maxConn; + pCfg->maxAclLen = aclDataLen; + pCfg->numTxBufs = 16; pCfg->numRxBufs = 8; - pCfg->numIsoTxBuf = 6; - pCfg->numIsoRxBuf = 6; - pCfg->maxIsoBufLen = 251; - pCfg->maxIsoPduLen = 64; - pCfg->maxCig = LL_MAX_CIG; - pCfg->maxCis = LL_MAX_CIS; - pCfg->subEvtSpaceDelay = 0; + pCfg->numIsoTxBuf = 16; + pCfg->numIsoRxBuf = 8; + pCfg->maxIsoSduLen = aclDataLen; + pCfg->maxIsoPduLen = 251; + pCfg->maxCig = maxGroup; + pCfg->maxCis = maxStream; + pCfg->cisSubEvtSpaceDelay = 0; + pCfg->maxBig = maxGroup; + pCfg->maxBis = maxStream; } /*************************************************************************************************/ @@ -168,8 +164,6 @@ void palCfgLoadLlParams(uint8_t *pConfig) * \brief Load device address. * * \param pDevAddr device address. - * - * \return None. */ /*************************************************************************************************/ void palCfgLoadBdAddress(uint8_t *pDevAddr) @@ -195,8 +189,6 @@ void palCfgLoadBdAddress(uint8_t *pDevAddr) * \brief Load 15.4 address. * * \param pDevAddr device address. - * - * \return None. */ /*************************************************************************************************/ void palCfgLoadExtMac154Address(uint8_t *pDevAddr) @@ -220,13 +212,12 @@ void palCfgLoadExtMac154Address(uint8_t *pDevAddr) * \brief Set device UUID. * * \param pBuf Return device UUID. - * - * \return None. */ /*************************************************************************************************/ void PalCfgSetDeviceUuid(uint8_t *pBuf) { - /* Not used on this platform. */ + /* Not used on this platform. */ + (void)pBuf; } /*************************************************************************************************/ @@ -234,8 +225,6 @@ void PalCfgSetDeviceUuid(uint8_t *pBuf) * \brief Load device UUID. * * \param pDevUuid Return device UUID. - * - * \return None. */ /*************************************************************************************************/ void palCfgLoadDeviceUuid(uint8_t *pDevUuid) @@ -263,12 +252,12 @@ void palCfgLoadDeviceUuid(uint8_t *pDevUuid) * \param cfgId Configuration ID. * \param pBuf Buffer. * \param len Buffer length. - * - * \return None. */ /*************************************************************************************************/ -void PalCfgLoadData(uint8_t cfgId, uint8_t *pBuf, uint32_t len) +void PalCfgLoadData(uint8_t cfgId, void *pBuf, uint32_t len) { + (void)len; + switch (cfgId) { case PAL_CFG_ID_BD_ADDR: diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c index 0242a6d0b29..802215868fe 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c @@ -5,14 +5,15 @@ * \brief Crypto driver implementation. * * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,24 +22,25 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_types.h" -#include "stack/platform/include/pal_bb_ble.h" -#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION -#include "crys_rsa_kg.h" -#include "crys_dh.h" -#include "ssi_pal_types.h" -#include "ssi_aes.h" -#include "sns_silib.h" -#include "crys_aesccm.h" -#endif +#include "pal_crypto.h" +#include "pal_bb_ble.h" +#include /* Nordic specific definitions. */ #include "nrf_ecb.h" #include "nrf.h" -#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION + +#if defined(NRF52840_XXAA) #include "nrf52840.h" +/* Crypto Cell definitions */ +#include "crys_rsa_kg.h" +#include "crys_dh.h" +#include "crys_aesccm.h" +#include "ssi_pal_types.h" +//#include "ssi_pal_mem.h" +#include "sns_silib.h" +#include "ssi_aes.h" #endif -#include /************************************************************************************************** Macros @@ -82,16 +84,8 @@ enum #endif -#ifndef LL_MAX_CONN -#define LL_MAX_CONN 4 /*!< Absolute maximum number of connections (maximum is 32). */ -#endif - -#ifndef LL_MAX_CIG -#define LL_MAX_CIG 2 /*!< Absolute maximum number of connected isochronous groups. */ -#endif - -#ifndef LL_MAX_CIS -#define LL_MAX_CIS 2 /*!< Absolute maximum number of connected isochronous streams per CIG. */ +#ifndef PAL_CRYPTO_MAX_ID +#define PAL_CRYPTO_MAX_ID 14 /*!< Absolute maximum number of cipher blocks. */ #endif #ifndef BB_ENABLE_INLINE_ENC_TX @@ -110,15 +104,13 @@ enum typedef union { uint8_t b[BB_AES_BLOCK_SIZE]; /*!< Byte access block. */ - uint32_t w[BB_AES_BLOCK_SIZE / sizeof(uint32_t)]; /*!< Word acess block. */ + uint32_t w[BB_AES_BLOCK_SIZE / sizeof(uint32_t)]; /*!< Word access block. */ struct { uint8_t flags[1]; /*!< Flags. */ uint8_t pctr[5]; /*!< Control. */ - uint8_t iv[8]; /*!< iv. */ - uint8_t iMSO[1]; /*!< iMSO. */ - uint8_t iLSO[1]; /*!< iLSO. */ + uint8_t iv[8]; /*!< IV. */ } f; /*!< Field access. */ } palCryptoCipherBlk_t; @@ -144,7 +136,7 @@ typedef union **************************************************************************************************/ /*! \brief Cipher block context. */ -static palCryptoCipherBlk_t palCryptoCipherBlkTbl[LL_MAX_CONN+LL_MAX_CIS*LL_MAX_CIG][PAL_CRYPTO_MODE_TOTAL]; +static palCryptoCipherBlk_t palCryptoCipherBlkTbl[PAL_CRYPTO_MAX_ID][PAL_CRYPTO_MODE_TOTAL]; /*! \brief Nordic ECB encryption data block. */ static palCryptoEcbData_t palCryptoEcb; @@ -153,11 +145,104 @@ static palCryptoEcbData_t palCryptoEcb; Functions **************************************************************************************************/ +/*************************************************************************************************/ +/*! + * \brief XOR block. + */ +/*************************************************************************************************/ +static void palXor128(const uint8_t *pInA, const uint8_t *pInB, uint8_t *pOut) +{ + const uint32_t *pInA_w = (uint32_t *)pInA; + const uint32_t *pInB_w = (uint32_t *)pInB; + uint32_t *pOut_w = (uint32_t *)pOut; + + pOut_w[0] = pInA_w[0] ^ pInB_w[0]; + pOut_w[1] = pInA_w[1] ^ pInB_w[1]; + pOut_w[2] = pInA_w[2] ^ pInB_w[2]; + pOut_w[3] = pInA_w[3] ^ pInB_w[3]; +} + +/*************************************************************************************************/ +/*! + * \brief Shift block left by 1 bit. + */ +/*************************************************************************************************/ +void palShiftLeft128(const uint8_t *pIn, uint8_t *pOut) +{ + uint8_t of = 0; + + for (int i = 15; i >= 0; i--) + { + pOut[i] = pIn[i] << 1; + pOut[i] |= of; + + of = pIn[i] >> 7; + } +} + +/*************************************************************************************************/ +/*! + * \brief Generate subkeys. + */ +/*************************************************************************************************/ +static void palGenSubkey(const uint8_t *pKey, uint8_t *pK1, uint8_t *pK2) +{ + static const uint8_t Rb[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }; + + unsigned char L[16]; + unsigned char Z[16] = { 0 }; + unsigned char t[16]; + + while (nrf_ecb_crypt(L, Z) != TRUE); + + if ((L[0] & 0x80) == 0) + { + palShiftLeft128(L, pK1); + } + else + { + palShiftLeft128(L, t); + palXor128(t, Rb, pK1); + } + + if ((pK1[0] & 0x80) == 0) + { + palShiftLeft128(pK1, pK2); + } + else + { + palShiftLeft128(pK1, t); + palXor128(t, Rb, pK2); + } +} + +/*************************************************************************************************/ +/*! + * \brief Pad block. + */ +/*************************************************************************************************/ +static void palPadBlock(const uint8_t *pIn, uint8_t *pOut, uint8_t len) +{ + for (size_t i = 0; i < BB_AES_BLOCK_SIZE; i++) + { + if (i < len) + { + pOut[i] = pIn[i]; + } + else if (i == len) + { + pOut[i] = 0x80; + } + else + { + pOut[i] = 0x00; + } + } +} + /*************************************************************************************************/ /*! * \brief Execute Nordic AES ECB. - * - * \return None. */ /*************************************************************************************************/ static inline void palCryptoExecuteAesEcb(void) @@ -184,8 +269,6 @@ static inline void palCryptoExecuteAesEcb(void) * \brief Load Nordic AES ECB data. * * \param pEnc Encryption parameters. - * - * \return None. */ /*************************************************************************************************/ static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc) @@ -207,11 +290,9 @@ static inline void palCryptoLoadEcbData(PalCryptoEnc_t *pEnc) * \param pMic Inplace MIC buffer. * \param pBuf Inplace cleartext/ciphertext buffer. * \param pldLen Length of buffer payload. - * - * \return None. */ /*************************************************************************************************/ -static void PalCryptPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf, uint16_t pldLen) +static void palCryptoPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf, uint16_t pldLen) { /* X_1 := ECB(K, A_0) */ palCryptoEcb.w.clear[0] = pAx->w[0]; @@ -260,8 +341,6 @@ static void PalCryptPdu(palCryptoCipherBlk_t *pAx, uint8_t *pMic, uint8_t *pBuf, * \param pHdr Header buffer. * \param pBuf Inplace cleartext/ciphertext buffer. * \param pldLen Length of payload. - * - * \return None. */ /*************************************************************************************************/ static void palCryptoAuthPdu(uint8_t type, palCryptoCipherBlk_t *pBx, uint8_t *pMic, uint8_t *pHdr, uint8_t *pBuf, uint16_t pldLen) @@ -334,8 +413,6 @@ static void palCryptoAuthPdu(uint8_t type, palCryptoCipherBlk_t *pBx, uint8_t *p * \brief Increment cipher block packet counter. * * \param pCb Cipher block. - * - * \return None. */ /*************************************************************************************************/ static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb) @@ -367,8 +444,6 @@ static inline void palCryptoIncPktCnt(palCryptoCipherBlk_t *pCb) * * \param pCb Cipher block. * \param evtCnt Connection event counter. - * - * \return None. */ /*************************************************************************************************/ static inline void palCryptoLoadPktCnt(palCryptoCipherBlk_t *pCb, uint16_t evtCnt) @@ -389,11 +464,9 @@ static inline void palCryptoLoadPktCnt(palCryptoCipherBlk_t *pCb, uint16_t evtCn * * \param pCb Cipher block. * \param evtCnt Connection event counter. - * - * \return None. */ /*************************************************************************************************/ -static inline void palCryptoLoadCisPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pktCnt) +static inline void palCryptoLoadIsoPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pktCnt) { /* Pack connEventCounter. */ pCb->f.pctr[0] = pktCnt >> 0; @@ -414,8 +487,6 @@ static inline void palCryptoLoadCisPktCnt(palCryptoCipherBlk_t *pCb, uint64_t pk * \param pOut Output data. * \param pIn Input data. * - * \return None. - * * \note Packet length is 16 bytes. */ /*************************************************************************************************/ @@ -455,14 +526,86 @@ void PalCryptoAesEcb(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn) memcpy(pOut, revOut, sizeof(revOut)); } +/*************************************************************************************************/ +/*! + * \fn PalCryptoAesCmac + * + * \brief Calculate AES CMAC. + * + * \param pKey Encryption key. + * \param pOut Output data. + * \param pIn Input data. + * + * \note Packet length is 16 bytes. + */ +/*************************************************************************************************/ +void PalCryptoAesCmac(const uint8_t *pKey, uint8_t *pOut, const uint8_t *pIn, uint16_t len) +{ + uint32_t alignKey[4]; + memcpy(alignKey, pKey, sizeof(alignKey)); + + uint32_t revKey[4]; + revKey[0] = __REV(alignKey[3]); + revKey[1] = __REV(alignKey[2]); + revKey[2] = __REV(alignKey[1]); + revKey[3] = __REV(alignKey[0]); + + uint32_t *pIn_w = (uint32_t *)pIn; + uint32_t revIn[4]; + if (len == 16) + { + revIn[0] = __REV(pIn_w[3]); + revIn[1] = __REV(pIn_w[2]); + revIn[2] = __REV(pIn_w[1]); + revIn[3] = __REV(pIn_w[0]); + } + else + { + revIn[0] = __REV(pIn_w[0]); + } + + nrf_ecb_init(); + nrf_ecb_set_key((uint8_t *)revKey); + + uint8_t K1[BB_AES_BLOCK_SIZE], K2[BB_AES_BLOCK_SIZE]; + palGenSubkey(pKey, K1, K2); + + uint32_t alignM[4]; + if (len == BB_AES_BLOCK_SIZE) + { + /* Complete block. */ + palXor128((uint8_t *)revIn, K1, (uint8_t *)alignM); + } + else + { + uint32_t alignInPad[4]; + /* Partial block. */ + palPadBlock((uint8_t *)revIn, (uint8_t *)alignInPad, len); + palXor128((uint8_t *)alignInPad, K2, (uint8_t *)alignM); + } + + const uint32_t alignX[4] = { 0 }; + uint32_t alignY[4]; + palXor128((const uint8_t *)alignX, (uint8_t *)alignM, (uint8_t *)alignY); + + uint32_t alignOut[4]; + while (nrf_ecb_crypt((uint8_t *)alignOut, (uint8_t *)alignY) != TRUE); + + uint32_t revOut[4]; + revOut[0] = __REV(alignOut[3]); + revOut[1] = __REV(alignOut[2]); + revOut[2] = __REV(alignOut[1]); + revOut[3] = __REV(alignOut[0]); + + memcpy(pOut, revOut, sizeof(revOut)); +} + /*************************************************************************************************/ /*! * \brief Generate cryptographic grade random number. * * \param pBuf Buffer to store random number. * \param len Number of bytes. - * - * \return None. */ /*************************************************************************************************/ void PalCryptoGenerateRandomNumber(uint8_t *pBuf, uint8_t len) @@ -488,17 +631,21 @@ void PalCryptoGenerateRandomNumber(uint8_t *pBuf, uint8_t len) * \param id Context ID. * \param localDir Direction bit of local device (0=slave, 1=master). * - * \return None. - * * This routine completes the transformation in a blocking manner. * * \note Leave this implementation empty if inline hardware encryption is available. */ /*************************************************************************************************/ -void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir) +void PalCryptoAesEnable(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t localDir) { unsigned int mode; + if (id > PAL_CRYPTO_MAX_ID) + { + /* TODO handle error condition */ + return; + } + /* Clear */ memset(&palCryptoCipherBlkTbl[id], 0, sizeof(palCryptoCipherBlkTbl[id])); @@ -527,10 +674,6 @@ void PalCryptoAesSetupCipherBlock(PalCryptoEnc_t *pEnc, uint8_t id, uint8_t loca /* Store context. */ pEnc->pEncryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_ENC]; pEnc->pDecryptCtx = &palCryptoCipherBlkTbl[id][PAL_CRYPTO_MODE_DEC]; - -#if (BB_ENABLE_INLINE_ENC_TX || BB_ENABLE_INLINE_DEC_RX) - PalBbBleInlineEncryptDecryptSetDirection(localDir); -#endif } /*************************************************************************************************/ @@ -571,16 +714,16 @@ bool_t PalCryptoAesCcmEncrypt(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf pHdr[BB_DATA_PDU_LEN_OFFSET] += PAL_CRYPTO_LL_DATA_MIC_LEN; /* Add length of MIC to payload. */ } - if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EVT_CNTR) && + if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT16_CNTR) && (pEnc->pEventCounter)) { palCryptoLoadPktCnt(pCb, *pEnc->pEventCounter + 1); } - if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) && - (pEnc->pCisTxPktCounter)) + if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) && + (pEnc->pTxPktCounter)) { - palCryptoLoadCisPktCnt(pCb, *pEnc->pCisTxPktCounter); + palCryptoLoadIsoPktCnt(pCb, *pEnc->pTxPktCounter); } palCryptoLoadEcbData(pEnc); @@ -590,7 +733,7 @@ bool_t PalCryptoAesCcmEncrypt(PalCryptoEnc_t *pEnc, uint8_t *pHdr, uint8_t *pBuf palCryptoAuthPdu(pEnc->type, pCb, pMic, pHdr, pBuf, pldLen); } - PalCryptPdu(pCb, pMic, pBuf, pldLen); + palCryptoPdu(pCb, pMic, pBuf, pldLen); if (pEnc->nonceMode == PAL_BB_NONCE_MODE_PKT_CNTR) { @@ -646,7 +789,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf) } uint8_t *pMic = pBuf + pldLen; - if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EVT_CNTR) && + if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT16_CNTR) && (pEnc->pEventCounter)) { /* Synchronized event counter stored in packet headroom. */ @@ -657,14 +800,14 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf) palCryptoLoadPktCnt(pCb, eventCounter); } - if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_CIS_CNTR) && - (pEnc->pCisRxPktCounter)) + if ((pEnc->nonceMode == PAL_BB_NONCE_MODE_EXT64_CNTR) && + (pEnc->pRxPktCounter)) { - palCryptoLoadCisPktCnt(pCb, *pEnc->pCisRxPktCounter - 1); /* Rx counter is already incremented when packet is received in the LCTR layer. Need to decrement one here. */ + palCryptoLoadIsoPktCnt(pCb, *pEnc->pRxPktCounter); } palCryptoLoadEcbData(pEnc); - PalCryptPdu(pCb, pMic, pBuf, pldLen); + palCryptoPdu(pCb, pMic, pBuf, pldLen); if (pEnc->enaAuth) { @@ -691,7 +834,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf) return TRUE; } -#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION +#if defined(NRF52840_XXAA) /*************************************************************************************************/ /*! * \brief Execute the CCM-Mode encryption algorithm. @@ -719,6 +862,10 @@ void PalCryptoCcmEnc(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pPlainText, CRYS_AESCCM_Key_t key; + (void)handlerId; + (void)param; + (void)event; + /* Copy key */ memcpy(key, pKey, SEC_CCM_KEY_LEN); @@ -756,6 +903,10 @@ uint32_t PalCryptoCcmDec(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pCypherT CRYS_AESCCM_Key_t key; + (void)handlerId; + (void)param; + (void)event; + /* Copy key */ memcpy(key, pKey, SEC_CCM_KEY_LEN); @@ -773,8 +924,6 @@ uint32_t PalCryptoCcmDec(const uint8_t *pKey, uint8_t *pNonce, uint8_t *pCypherT /*************************************************************************************************/ /*! * \brief Called to initialize CCM-Mode security. - * - * \return None. */ /*************************************************************************************************/ void PalCryptoInit(void) @@ -787,8 +936,6 @@ void PalCryptoInit(void) /*************************************************************************************************/ /*! * \brief Called to De-initialize CCM-Mode security. - * - * \return None. */ /*************************************************************************************************/ void PalCryptoDeInit(void) @@ -806,8 +953,6 @@ void PalCryptoDeInit(void) * * \param pEnc Encryption parameters. * \param pktCnt Counter value. - * - * \return None. */ /*************************************************************************************************/ #if (BB_ENABLE_INLINE_ENC_TX) @@ -823,8 +968,6 @@ void PalCryptoSetEncryptPacketCount(PalCryptoEnc_t *pEnc, uint64_t pktCnt) * * \param pEnc Encryption parameters. * \param pktCnt Counter value. - * - * \return None. */ /*************************************************************************************************/ #if (BB_ENABLE_INLINE_DEC_RX) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c index 5b6da04d845..c114b632625 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c @@ -5,14 +5,15 @@ * \brief LED driver implementation. * * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,207 +22,126 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_led.h" -#include "boards.h" -#include "stack/platform/include/pal_types.h" - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#define PAL_LED0_MASK 0x00002000 -#define PAL_LED1_MASK 0x00004000 -#define PAL_LED2_MASK 0x00008000 -#define PAL_LED3_MASK 0x00010000 - -/*! \brief LED masks. */ -#if (AUDIO_CAPE == 1) - -#define PAL_LED_AUDIO_LED1_MASK 0x00000002 -#define PAL_LED_AUDIO_LED2_MASK 0x00000004 -#define PAL_LED_AUDIO_LED3_MASK 0x00000008 -#define PAL_LED_AUDIO_LED4_MASK 0x00000010 -#define PAL_LED_AUDIO_LED5_MASK 0x00000020 -#define PAL_LED_AUDIO_LED6_MASK 0x00000040 - -#define PAL_LED_P0_MASK 0x01E000 -#define PAL_LED_P1_MASK 0x00007E - -#else -#define PAL_LED_P0_MASK 0x01E000 -#define PAL_LED_P1_MASK 0x000000 +#include "pal_led.h" +#if defined(BOARD_PCA10056) +#include "boards.h" +#include "nrfx_gpiote.h" #endif -/*! \brief Invalid LED mask. */ -#define PAL_LED_INVALID_MASK 0xFF - -/*! \brief LED count using GPIO P0. */ -#define PAL_LED_COUNT_P0 0x04 - -/*! \brief I/O Expander definitions */ -enum -{ - PAL_LED_IO_EXP_SUB_ADDR = 0x06 /*!< Lower 3 bit of I/O expander address connected with LEDs. */ -}; - -/*! \brief I/O Expander accessories */ -enum -{ - PAL_LED_IO_EXP_CONFIG = 0x00 /*!< LED3 to LED10 are defined as outputs.*/ -}; - -#ifdef DEBUG - -/*! \brief Parameter check. */ -#define PAL_LED_PARAM_CHECK(expr) { if (!(expr)) { return; } } - -/*! \brief Parameter check, with return value. */ -#define PAL_LED_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { return (rv); } } - -#else - -/*! \brief Parameter check (disabled). */ -#define PAL_LED_PARAM_CHECK(expr) - -/*! \brief Parameter check, with return value (disabled). */ -#define PAL_LED_PARAM_CHECK_RET(expr, rv) - +#if defined(BOARD_NRF6832) +#include "lp5562.h" #endif /************************************************************************************************** Functions: Initialization **************************************************************************************************/ +#if defined(BOARD_NRF6832) /*************************************************************************************************/ /*! - * \brief Get LED pin number from LED ID. + * \brief Map LED ID to physical LED. * * \param ledId LED ID. * - * \return LED pin mask. + * \return Mapped physical LED. */ /*************************************************************************************************/ -static uint32_t palLedGetPinMask(uint8_t ledId) +static int palLedMapId(uint8_t ledId) { - uint32_t ledMask = PAL_LED_INVALID_MASK; - switch (ledId) { - case PAL_LED_ID_CPU_ACTIVE: - ledMask = PAL_LED1_MASK; - break; - + /* Predefined */ case PAL_LED_ID_ERROR: - ledMask = PAL_LED3_MASK; + return LP5562_LED_W; /* bottom */ break; + /* Application defined */ case 0: - ledMask = PAL_LED0_MASK; - break; + return LP5562_LED_R; /* top/left */ case 1: - ledMask = PAL_LED1_MASK; - break; + return LP5562_LED_G; /* top/middle */ case 2: - ledMask = PAL_LED2_MASK; - break; - case 3: - ledMask = PAL_LED3_MASK; - break; - -#if (AUDIO_CAPE == 1) - case 4: - ledMask = PAL_LED_AUDIO_LED1_MASK; - break; - case 5: - ledMask = PAL_LED_AUDIO_LED2_MASK; - break; - case 6: - ledMask = PAL_LED_AUDIO_LED3_MASK; - break; - case 7: - ledMask = PAL_LED_AUDIO_LED4_MASK; - break; - case 8: - ledMask = PAL_LED_AUDIO_LED5_MASK; - break; - case 9: - ledMask = PAL_LED_AUDIO_LED6_MASK; - break; -#endif + return LP5562_LED_B; /* top/right */ + /* Ignore */ + case PAL_LED_ID_CPU_ACTIVE: default: - ledMask = PAL_LED_INVALID_MASK; break; } - return ledMask; + return -1; } +#endif /*************************************************************************************************/ /*! * \brief Initialize LEDs. - * - * \return None. */ /*************************************************************************************************/ void PalLedInit(void) { - nrf_gpio_port_dir_output_set(NRF_P0, PAL_LED_P0_MASK); - nrf_gpio_port_out_set(NRF_P0, PAL_LED_P0_MASK); -#if (GPIO_COUNT > 1) - nrf_gpio_port_dir_output_set(NRF_P1, PAL_LED_P1_MASK); - nrf_gpio_port_out_set(NRF_P1, PAL_LED_P1_MASK); +#if defined(BOARD_PCA10056) + nrfx_err_t err; + + if (!nrfx_gpiote_is_init()) + { + err = nrfx_gpiote_init(); + + if (err != NRFX_SUCCESS) + { + return; + } + } + + nrfx_gpiote_out_config_t cfg = NRFX_GPIOTE_CONFIG_OUT_SIMPLE(true); + + nrfx_gpiote_out_init(LED_1, &cfg); + nrfx_gpiote_out_init(LED_2, &cfg); + nrfx_gpiote_out_init(LED_3, &cfg); + nrfx_gpiote_out_init(LED_4, &cfg); +#endif + +#if AUDIO_CAPE + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 1), &cfg); + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 2), &cfg); + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 3), &cfg); + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 4), &cfg); + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 5), &cfg); + nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 6), &cfg); +#endif + +#if defined(BOARD_NRF6832) + lp5562_LedInit(); #endif } /*************************************************************************************************/ /*! * \brief De-initialize LEDs. - * - * \return None. */ /*************************************************************************************************/ void PalLedDeInit(void) { - nrf_gpio_port_dir_input_set(NRF_P0, PAL_LED_P0_MASK); -#if (GPIO_COUNT > 1) - nrf_gpio_port_dir_input_set(NRF_P1, PAL_LED_P1_MASK); +#if defined(BOARD_PCA10056) + nrfx_gpiote_out_uninit(LED_1); + nrfx_gpiote_out_uninit(LED_2); + nrfx_gpiote_out_uninit(LED_3); + nrfx_gpiote_out_uninit(LED_4); #endif -} - -/*************************************************************************************************/ -/*! - * \brief Set multiple LEDs on. - * - * \param mask LED mask. - * - * \return None. - * - */ -/*************************************************************************************************/ -void PalLedOnGroup(uint32_t mask) -{ - PAL_LED_PARAM_CHECK(mask); - - nrf_gpio_port_out_clear(NRF_P0, mask); -} -/*************************************************************************************************/ -/*! - * \brief Set multiple LEDs off. - * - * \param mask LED mask. - * - * \return None. - * - */ -/*************************************************************************************************/ -void PalLedOffGroup(uint32_t mask) -{ - PAL_LED_PARAM_CHECK(mask); +#if defined(BOARD_NRF6832) + lp5562_LedDeInit(); +#endif - nrf_gpio_port_out_set(NRF_P0, mask); +#if AUDIO_CAPE + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 1)); + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 2)); + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 3)); + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 4)); + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 5)); + nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 6)); +#endif } /*************************************************************************************************/ @@ -229,24 +149,61 @@ void PalLedOffGroup(uint32_t mask) * \brief Set LED on. * * \param ledId LED ID. - * - * \return None. - * */ /*************************************************************************************************/ void PalLedOn(uint8_t ledId) { - uint32_t ledMask = palLedGetPinMask(ledId); - PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK); +#if defined(BOARD_PCA10056) + switch (ledId) + { + case PAL_LED_ID_CPU_ACTIVE: + nrfx_gpiote_out_clear(LED_2); + break; + case PAL_LED_ID_ERROR: + nrfx_gpiote_out_clear(LED_4); + break; + case 0: + nrfx_gpiote_out_clear(LED_1); + break; + case 1: + nrfx_gpiote_out_clear(LED_3); + break; + default: + break; + } +#endif - if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE)) +#if defined(BOARD_NRF6832) + int ledPin = palLedMapId(ledId); + if (ledPin >= 0) { - nrf_gpio_port_out_clear(NRF_P0, ledMask); + lp5562_LedOn(ledPin); } -#if (GPIO_COUNT > 1) - else +#endif + +#if AUDIO_CAPE + switch (ledId) { - nrf_gpio_port_out_clear(NRF_P1, ledMask); + case 2: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 1)); + break; + case 3: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 2)); + break; + case 4: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 3)); + break; + case 5: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 4)); + break; + case 6: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 5)); + break; + case 7: + nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 6)); + break; + default: + break; } #endif } @@ -256,24 +213,61 @@ void PalLedOn(uint8_t ledId) * \brief Set LED off. * * \param ledId LED ID. - * - * \return None. - * */ /*************************************************************************************************/ void PalLedOff(uint8_t ledId) { - uint32_t ledMask = palLedGetPinMask(ledId); - PAL_LED_PARAM_CHECK(ledMask != PAL_LED_INVALID_MASK); +#if defined(BOARD_PCA10056) + switch (ledId) + { + case PAL_LED_ID_CPU_ACTIVE: + nrfx_gpiote_out_set(LED_2); + break; + case PAL_LED_ID_ERROR: + nrfx_gpiote_out_set(LED_4); + break; + case 0: + nrfx_gpiote_out_set(LED_1); + break; + case 1: + nrfx_gpiote_out_set(LED_3); + break; + default: + break; + } +#endif - if ((ledId < PAL_LED_COUNT_P0) || (ledId >= PAL_LED_ID_CPU_ACTIVE)) +#if defined(BOARD_NRF6832) + int ledPin = palLedMapId(ledId); + if (ledPin >= 0) { - nrf_gpio_port_out_set(NRF_P0, ledMask); + lp5562_LedOff(ledPin); } -#if (GPIO_COUNT > 1) - else +#endif + +#if AUDIO_CAPE + switch (ledId) { - nrf_gpio_port_out_set(NRF_P1, ledMask); + case 2: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 1)); + break; + case 3: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 2)); + break; + case 4: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 3)); + break; + case 5: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 4)); + break; + case 6: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 5)); + break; + case 7: + nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 6)); + break; + default: + break; } #endif } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c index ebdf3d95f5f..084485e0197 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c @@ -5,50 +5,139 @@ * \brief Tickless timer implementation. * * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Notes: + * + * This is timer driver is used by wsf_timer.c and pal_timer.c. + * */ /*************************************************************************************************/ #include "nrf.h" -#include "stack/platform/include/pal_rtc.h" +#include "pal_rtc.h" +#include "pal_timer.h" + +/************************************************************************************************** + Macros +**************************************************************************************************/ + +#ifdef DEBUG + +/*! \brief Parameter and state check. */ +#define PAL_RTC_CHECK(expr) { if (!(expr)) { while(1); } } + +#else + +/*! \brief Parameter and state check (disabled). */ +#define PAL_RTC_CHECK(expr) + +#endif + +#define RTC_TIMER_TOTAL_CHANNEL 4 + +/************************************************************************************************** + Variables +**************************************************************************************************/ + +static palRtcIrqCback_t palRtcTimerCback[RTC_TIMER_TOTAL_CHANNEL]; + +/*************************************************************************************************/ +/*! + * \brief Function for clearing rtc events. + * + * \param channelId Channel ID Number. + */ +/*************************************************************************************************/ +void PalRtcClearCompareEvents(uint8_t channelId) +{ + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + + NRF_RTC1->EVENTS_COMPARE[channelId] = 0; + (void)NRF_RTC1->EVENTS_COMPARE[channelId]; +} /*************************************************************************************************/ /*! * \brief Function for starting the RTC timer. * - * \return None. + * \param channelId Channel ID Number. */ /*************************************************************************************************/ -void PalRtcEnableCompareIrq(void) +void PalRtcEnableCompareIrq(uint8_t channelId) { - NRF_RTC0->EVENTS_COMPARE[0] = 0; - NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk; - NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + + PalRtcClearCompareEvents(channelId); + + switch (channelId) + { + case 0: + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; + break; + case 1: + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE1_Msk; + break; + case 2: + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE2_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE2_Msk; + break; + case 3: + NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE3_Msk; + NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE3_Msk; + break; + default: + break; + } } /*************************************************************************************************/ /*! * \brief Function for stopping the RTC timer. * - * \return None. + * \param channelId Channel ID Number. */ /*************************************************************************************************/ -void PalRtcDisableCompareIrq(void) +void PalRtcDisableCompareIrq(uint8_t channelId) { - NRF_RTC0->INTENCLR = RTC_INTENCLR_COMPARE0_Msk; - NRF_RTC0->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk; + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + + switch (channelId) + { + case 0: + NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE0_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk; + break; + case 1: + NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE1_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; + break; + case 2: + NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE2_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; + break; + case 3: + NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE3_Msk; + NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE3_Msk; + break; + default: + break; + } } /*************************************************************************************************/ @@ -63,81 +152,109 @@ uint32_t PalRtcCounterGet(void) NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} - NRF_RTC0->TASKS_STOP = 0; + NRF_RTC1->TASKS_STOP = 0; - return NRF_RTC0->COUNTER; + return NRF_RTC1->COUNTER; } /*************************************************************************************************/ /*! * \brief Set the RTC capture compare value. * + * \param channelId Channel ID Number. * \param value Set new value for compare value. - * - * \return None */ /*************************************************************************************************/ -void PalRtcCompareSet(uint32_t value) +void PalRtcCompareSet(uint8_t channelId, uint32_t value) { - NRF_RTC0->CC[0] = value; + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + NRF_RTC1->CC[channelId] = value; } /*************************************************************************************************/ /*! * \brief Get the current value of the RTC capture compare. * + * \param channelId Channel ID Number. + * * \return Current value of the capture compare. */ /*************************************************************************************************/ -uint32_t PalRtcCompareGet(void) +uint32_t PalRtcCompareGet(uint8_t channelId) { - return NRF_RTC0->CC[0]; + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + return NRF_RTC1->CC[channelId]; } /*************************************************************************************************/ /*! * \brief RTC interrupt handler. * - * \return None. - * * This handler stores the RTC start time which is used as a reference to compute the receive * packet timestamp using the HFCLK. * */ /*************************************************************************************************/ -void RTC0_IRQHandler(void) +void RTC1_IRQHandler(void) { - if (NRF_RTC0->EVENTS_COMPARE[0]) + for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++) { - /* clear the interrupt */ - NRF_RTC0->EVENTS_COMPARE[0] = 0; - (void)NRF_RTC0->EVENTS_COMPARE[0]; /* wait for write buffer to empty */ + if (NRF_RTC1->EVENTS_COMPARE[channelId]) + { + PalRtcClearCompareEvents(channelId); + + if (palRtcTimerCback[channelId]) + { + palRtcTimerCback[channelId](); + } + } } } /*************************************************************************************************/ /*! * \brief Tickless timer initialization routine. - * - * \return None. */ /*************************************************************************************************/ void PalRtcInit(void) { /* Stop RTC to prevent any running timers from expiring. */ - PalRtcDisableCompareIrq(); + for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++) + { + PalRtcDisableCompareIrq(channelId); + } + + /* Configure low-frequency clock. */ + NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; NRF_CLOCK->TASKS_LFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} - NRF_RTC0->TASKS_STOP = 0; + while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { } + NRF_RTC1->TASKS_STOP = 0; + + NRF_RTC1->TASKS_STOP = 1; + NRF_RTC1->TASKS_CLEAR = 1; + NRF_RTC1->PRESCALER = 0; /* clear prescaler */ + NRF_RTC1->TASKS_START = 1; - NRF_RTC0->TASKS_STOP = 1; - NRF_RTC0->TASKS_CLEAR = 1; - NRF_RTC0->PRESCALER = 0; /* clear prescaler */ - NRF_RTC0->TASKS_START = 1; + NVIC_SetPriority(RTC1_IRQn, 0x80); /* medium priority */ + NVIC_ClearPendingIRQ(RTC1_IRQn); + NVIC_EnableIRQ(RTC1_IRQn); +} - NVIC_SetPriority(RTC0_IRQn, 0x80); /* medium priority */ - NVIC_ClearPendingIRQ(RTC0_IRQn); - NVIC_EnableIRQ(RTC0_IRQn); +/*************************************************************************************************/ +/*! + * \brief Register rtc IRQ callback. + * + * \param channelId Channel ID Number. + * \param cback Call back for ISR. + * + * This callback is dedicated for scheduler timer in low power code. + * + */ +/*************************************************************************************************/ +void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback) +{ + PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); + palRtcTimerCback[channelId] = cback; } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c index 10235e70c4b..ccbd06dd58d 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c @@ -5,14 +5,15 @@ * \brief System hooks. * * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -22,11 +23,12 @@ /*************************************************************************************************/ #include "nrf.h" -#include "stack/platform/include/pal_bb.h" -#include "stack/platform/include/pal_rtc.h" -#include "stack/platform/include/pal_sys.h" -#include "stack/platform/include/pal_led.h" -#include "platform/mbed_power_mgmt.h" +#include "pal_rtc.h" +#include "pal_sys.h" +#include "pal_led.h" +#include "pal_timer.h" +#include "pal_bb.h" +#include "pal_uart.h" #include @@ -34,16 +36,37 @@ Macros **************************************************************************************************/ -extern uint8_t *SystemHeapStart; -extern uint32_t SystemHeapSize; - -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) +#ifdef __GNUC__ /*! \brief Stack initial values. */ -#define INIT_STACK_VAL 0xAFAFAFAF +#define INIT_STACK_VAL 0xAFAFAFAF + +/*! \brief Starting memory location of free memory. */ +#define FREE_MEM_START ((uint8_t *)&__heap_start__) + +/*! \brief Total size in bytes of free memory. */ +#define FREE_MEM_SIZE ((uint32_t)&__heap_end__ - (uint32_t)&__heap_start__) +extern uint8_t *SystemHeapStart; +extern uint32_t SystemHeapSize; + +extern unsigned long __text_end__; +extern unsigned long __data_start__; +extern unsigned long __data_end__; +extern unsigned long __bss_start__; +extern unsigned long __bss_end__; extern unsigned long __stack_top__; extern unsigned long __stack_limit__; +extern unsigned long __heap_end__; +extern unsigned long __heap_start__; + +#else + +/*! \brief Starting memory location of free memory. */ +#define FREE_MEM_START ((uint8_t *)palSysFreeMem) + +/*! \brief Total size in bytes of free memory. */ +#define FREE_MEM_SIZE (1024 * 196) #endif @@ -51,6 +74,21 @@ extern unsigned long __stack_limit__; Global Variables **************************************************************************************************/ +#ifdef __GNUC__ + +uint8_t *SystemHeapStart; +uint32_t SystemHeapSize; + +#else + +/*! \brief Free memory for pool buffers (align to word boundary). */ +uint32_t palSysFreeMem[FREE_MEM_SIZE/sizeof(uint32_t)]; + +uint8_t *SystemHeapStart = (uint8_t *) palSysFreeMem; +uint32_t SystemHeapSize = FREE_MEM_SIZE; + +#endif + /*! \brief Number of assertions. */ static uint32_t palSysAssertCount; @@ -66,19 +104,17 @@ static uint32_t palSysBusyCount; /*************************************************************************************************/ /*! * \brief Enter a critical section. - * - * \return None. */ /*************************************************************************************************/ -static inline void palEnterCs(void) +void PalEnterCs(void) { #ifdef __IAR_SYSTEMS_ICC__ __disable_interrupt(); #endif - #if defined(__GNUC__) && !defined(__ARMCC_VERSION) + #ifdef __GNUC__ __asm volatile ("cpsid i"); #endif - #if defined(__ARMCC_VERSION) + #ifdef __CC_ARM __disable_irq(); #endif } @@ -86,19 +122,17 @@ static inline void palEnterCs(void) /*************************************************************************************************/ /*! * \brief Exit a critical section. - * - * \return None. */ /*************************************************************************************************/ -static inline void palExitCs(void) +void PalExitCs(void) { #ifdef __IAR_SYSTEMS_ICC__ __enable_interrupt(); #endif - #if defined(__GNUC__) && !defined(__ARMCC_VERSION) + #ifdef __GNUC__ __asm volatile ("cpsie i"); #endif - #if defined(__ARMCC_VERSION) + #ifdef __CC_ARM __enable_irq(); #endif } @@ -106,34 +140,17 @@ static inline void palExitCs(void) /*************************************************************************************************/ /*! * \brief Common platform initialization. - * - * \return None. */ /*************************************************************************************************/ void PalSysInit(void) { - /* enable Flash cache */ + /* Enable Flash cache */ NRF_NVMC->ICACHECNF |= (NVMC_ICACHECNF_CACHEEN_Enabled << NVMC_ICACHECNF_CACHEEN_Pos); - /* switch to more accurate 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator) */ + /* Use 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator). */ NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) - { - } - - /* configure low-frequency clock */ - NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) - { - } - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - /* cycle radio peripheral power to guarantee known radio state */ - NRF_RADIO->POWER = 0; - NRF_RADIO->POWER = 1; + while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { } palSysAssertCount = 0; PalSysAssertTrapEnable = TRUE; @@ -141,6 +158,10 @@ void PalSysInit(void) PalRtcInit(); + PalLedInit(); + PalLedOff(PAL_LED_ID_ERROR); + PalLedOn(PAL_LED_ID_CPU_ACTIVE); + #ifdef DEBUG /* Reset free memory. */ memset(SystemHeapStart, 0, SystemHeapSize); @@ -150,12 +171,12 @@ void PalSysInit(void) /*************************************************************************************************/ /*! * \brief System fault trap. - * - * \return None. */ /*************************************************************************************************/ void PalSysAssertTrap(void) { + PalLedOn(PAL_LED_ID_ERROR); + palSysAssertCount++; while (PalSysAssertTrapEnable); @@ -166,8 +187,6 @@ void PalSysAssertTrap(void) * \brief Set system trap. * * \param enable Enable assert trap or not. - * - * \return None. */ /*************************************************************************************************/ void PalSysSetTrap(bool_t enable) @@ -178,8 +197,6 @@ void PalSysSetTrap(bool_t enable) /*************************************************************************************************/ /*! * \brief Get assert count. - * - * \return None. */ /*************************************************************************************************/ uint32_t PalSysGetAssertCount(void) @@ -196,7 +213,7 @@ uint32_t PalSysGetAssertCount(void) /*************************************************************************************************/ uint32_t PalSysGetStackUsage(void) { -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) +#ifdef __GNUC__ unsigned long *pUnused = &__stack_limit__; while (pUnused < &__stack_top__) @@ -219,28 +236,53 @@ uint32_t PalSysGetStackUsage(void) /*************************************************************************************************/ /*! * \brief System sleep. - * - * \return none. */ /*************************************************************************************************/ void PalSysSleep(void) { - sleep(); + /* Clock management for low power mode. */ + #if BB_CLK_RATE_HZ == 32768 + uint32_t rtcNow = NRF_RTC1->COUNTER; + + if ((BbGetCurrentBod() == NULL) && PalUartGetState(PAL_UART_ID_CHCI) == PAL_UART_STATE_UNINIT) + { + if ((PalTimerGetState() == PAL_TIMER_STATE_BUSY && + ((NRF_RTC1->CC[3] - rtcNow) & PAL_MAX_RTC_COUNTER_VAL) > PAL_HFCLK_OSC_SETTLE_TICKS) || + (PalTimerGetState() == PAL_TIMER_STATE_READY)) + { + /* disable HFCLK */ + NRF_CLOCK->TASKS_HFCLKSTOP = 1; + NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; + (void)NRF_CLOCK->EVENTS_HFCLKSTARTED; + } + } + #endif + + /* CPU sleep. */ + #ifdef __IAR_SYSTEMS_ICC__ + __wait_for_interrupt(); + #endif + #ifdef __GNUC__ + __asm volatile ("wfi"); + #endif + #ifdef __CC_ARM + __wfi(); + #endif } /*************************************************************************************************/ /*! * \brief Check if system is busy. * - * \return True if system is busy. + * \return TRUE if system is busy. */ /*************************************************************************************************/ bool_t PalSysIsBusy(void) { bool_t sysIsBusy = FALSE; - palEnterCs(); + PalEnterCs(); sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE); - palExitCs(); + PalExitCs(); return sysIsBusy; } @@ -253,24 +295,22 @@ bool_t PalSysIsBusy(void) /*************************************************************************************************/ void PalSysSetBusy(void) { - palEnterCs(); + PalEnterCs(); palSysBusyCount++; - palExitCs(); + PalExitCs(); } /*************************************************************************************************/ /*! * \brief Set system idle. - * - * \return none. */ /*************************************************************************************************/ void PalSysSetIdle(void) { - palEnterCs(); + PalEnterCs(); if (palSysBusyCount) { palSysBusyCount--; } - palExitCs(); + PalExitCs(); } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c index c9acf8da1e7..c2ec5f834d3 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c @@ -5,14 +5,15 @@ * \brief Timer driver * * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,22 +25,56 @@ /* * Notes: * - * This is timer driver dedicated to scheduler, an interrupt will be triggered to do scheduler task - * when timer hits compare value. TIMER2 is used here. + * This is timer driver used for scheduler and other low power related tasks. + * It has dependency on pal_rtc.c, and some scheduler and BB API due to the complexity explained below. + * This is not ideal and should be fixed later. + * + * If SCH_TIMER_REQUIRED == FALSE: + * No hardware timer is needed for scheduler. + * + * If SCH_TIMER_REQUIRED == TRUE and BB_CLK_RATE_HZ == 32768: + * RTC1 timer(channel 3) is in use for scheduler. + * + * If SCH_TIMER_REQUIRED == TRUE and BB_CLK_RATE_HZ == 1MHz or 8MHz: + * Timer1 is in used for scheduler. + * + * RTC1 timer(Channel 0) is required for wsf software timer no matter what options are chosen. + * + * RTC1 timer(Channel 1 and 2) are required as long as BB_CLK_RATE_HZ == 32768. + * + * NRF timer1's compare/capture registers are assigned specific uses: + * CC[0] - Compare value for timer expiry interrupt. + * CC[1] - manual capture of current time. * - * TIMER2's compare/capture registers are assigned specific uses: - * CC[0] - Compare value for timer expiry interrupt - * CC[1] - manual capture of current time + * NRF RTC1's compare/capture registers are assigned specific uses: + * CC[0] - Compare value for wsf software timer interrupt. + * CC[1] - Compare value for NRF timer0 start task. + * CC[2] - Compare value for NRF HFCLK start task. + * CC[3] - Compare value for scheduler load interrupt. * */ +#include "pal_timer.h" +#include "pal_rtc.h" +#include "sch_api.h" +#include "bb_api.h" + #include "nrf.h" -#include "stack/platform/include/pal_timer.h" #include "nrf_gpio.h" /************************************************************************************************** Macros **************************************************************************************************/ + +/*! \brief Ticks and microseconds conversion. */ +#if BB_CLK_RATE_HZ == 32768 + #define PAL_TIMER_US_TO_TICKS(us) ((uint32_t)(((uint64_t)(us) * (uint64_t)(70368745)) >> 31)) /* calculated value may be one tick low */ + #define PAL_TIMER_TICKS_TO_US(ticks) ((uint32_t)(((uint64_t)(ticks) * 15625) >> 9)) +#else + #define PAL_TIMER_US_TO_TICKS(us) (us) + #define PAL_TIMER_TICKS_TO_US(ticks) (ticks) +#endif + #ifdef DEBUG /*! \brief Parameter and state check. */ @@ -53,12 +88,20 @@ #endif /* Scheduler timer resolution is fixed at 1us per tick. */ -#define PAL_TIMER_1MHZ_PRESCALER 4 +#define PAL_TIMER_1MHZ_PRESCALER 4 #ifdef DEBUG -#define PAL_TIMER_DEBUG_0_PIN 35 /* P1.03 */ +#define PAL_TIMER_DEBUG_0_PIN 35 /* P1.03 */ #endif +/* Predefined channel ID for timer1 and rtc1. */ +#define TIMER_CHANNEL_START_BB 0 +#define TIMER_CHANNEL_READ_TICK 1 + +#define RTC_CHANNEL_START_HFCLK 2 +#define RTC_CHANNEL_START_BB 3 + + /************************************************************************************************** Global Variables **************************************************************************************************/ @@ -71,6 +114,38 @@ static struct PalTimerCompCback_t expCback; /*!< Timer expiry call back function. */ } palTimerCb; +/* Nordic specific internal functions. */ +extern void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback); +extern void PalRtcClearCompareEvents(uint8_t channelId); + +#if BB_CLK_RATE_HZ == 32768 +/*************************************************************************************************/ +/*! + * \brief scheduler callback handler from RTC interrupt. + */ +/*************************************************************************************************/ +static void palTimerRtcIrqHandler(void) +{ + #ifdef DEBUG + nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN); + #endif + + PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY); + + palTimerCb.state = PAL_TIMER_STATE_READY; + + if (palTimerCb.expCback) + { + palTimerCb.expCback(); + } + + #ifdef DEBUG + nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN); + #endif +} +#endif + +#if SCH_TIMER_REQUIRED /*************************************************************************************************/ /*! * \brief Get the current tick of the scheduler timer. @@ -78,60 +153,69 @@ static struct * \return Current tick of the scheduler timer. */ /*************************************************************************************************/ -uint32_t PalTimerGetCurrentTime(void) +static uint32_t palTimerGetCurrentTime(void) { /* Only valid for initialized scheduler timer. */ - if (palTimerCb.state) { - /* Capture current TIMER2 count to capture register 1 */ - NRF_TIMER2->TASKS_CAPTURE[1] = 1; - /* Read and return the captured count value from capture register 1 */ - return NRF_TIMER2->CC[1]; + #if BB_CLK_RATE_HZ == 32768 + /* Read and return the captured count value from capture register 1 */ + return PalRtcCounterGet(); + #else + /* Capture current TIMER1 count to capture register 1 */ + NRF_TIMER1->TASKS_CAPTURE[TIMER_CHANNEL_READ_TICK] = 1; + /* Read and return the captured count value from capture register 1 */ + return NRF_TIMER1->CC[TIMER_CHANNEL_READ_TICK]; + #endif } - return 0; } +#endif /*************************************************************************************************/ /*! * \brief Initialize the scheduler timer. * * \param expCback Timer expire call back function. - * - * \return None. */ /*************************************************************************************************/ void PalTimerInit(PalTimerCompCback_t expCback) { -#ifdef DEBUG - nrf_gpio_cfg_output(PAL_TIMER_DEBUG_0_PIN); -#endif + #ifdef DEBUG + nrf_gpio_cfg_output(PAL_TIMER_DEBUG_0_PIN); + #endif PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_UNINIT); PAL_TIMER_CHECK(expCback != NULL); - /* Give scheduler timer the highest priority. */ - NVIC_SetPriority(TIMER2_IRQn, 0); + #if SCH_TIMER_REQUIRED == TRUE + #if BB_CLK_RATE_HZ == 32768 + PalRtcIrqRegister(RTC_CHANNEL_START_BB, palTimerRtcIrqHandler); + #else + /* Give scheduler timer the highest priority. */ + NVIC_SetPriority(TIMER1_IRQn, 0); /* highest priority */ + NVIC_DisableIRQ(TIMER1_IRQn); - /* stop timer if it was somehow running (timer must be stopped for configuration) */ - NRF_TIMER2->TASKS_STOP = 1; + /* stop timer if it was somehow running (timer must be stopped for configuration) */ + NRF_TIMER1->TASKS_STOP = 1; - /* clear timer to zero count */ - NRF_TIMER2->TASKS_CLEAR = 1; + /* clear timer to zero count */ + NRF_TIMER1->TASKS_CLEAR = 1; - /* configure timer */ - NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; - NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit; - NRF_TIMER2->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */ + /* configure timer */ + NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; + NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + NRF_TIMER1->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */ - /* TIMER2 is a free running clock. */ - NRF_TIMER2->TASKS_START = 1; + /* timer1 is a free running clock. */ + NRF_TIMER1->TASKS_START = 1; - /* Clear out and enable TIMER2 interrupt at system level. */ - NRF_TIMER2->INTENCLR = 0xFFFFFFFF; - NRF_TIMER2->EVENTS_COMPARE[0] = 0; - NVIC_ClearPendingIRQ(TIMER2_IRQn); - NVIC_EnableIRQ(TIMER2_IRQn); + /* Clear out and enable timer1 interrupt at system level. */ + NRF_TIMER1->INTENCLR = 0xFFFFFFFF; + NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; + NVIC_ClearPendingIRQ(TIMER1_IRQn); + NVIC_EnableIRQ(TIMER1_IRQn); + #endif + #endif palTimerCb.compareVal = 0; palTimerCb.expCback = expCback; @@ -141,18 +225,18 @@ void PalTimerInit(PalTimerCompCback_t expCback) /*************************************************************************************************/ /*! * \brief De-initialize the scheduler timer. - * - * \return None. */ /*************************************************************************************************/ void PalTimerDeInit(void) { + #if SCH_TIMER_REQUIRED == TRUE + #if BB_CLK_RATE_HZ != 32768 + NVIC_DisableIRQ(TIMER1_IRQn); - NVIC_DisableIRQ(TIMER2_IRQn); - - /* stop timer */ - NRF_TIMER2->TASKS_STOP = 1; - NRF_TIMER2->TASKS_SHUTDOWN = 1; + /* stop timer */ + NRF_TIMER1->TASKS_STOP = 1; + #endif + #endif palTimerCb.state = PAL_TIMER_STATE_UNINIT; } @@ -174,69 +258,95 @@ PalTimerState_t PalTimerGetState(void) * \brief Start the scheduler timer. * * \param expTimeUsec Set timer expiry in microseconds. - * - * \return None */ /*************************************************************************************************/ - void PalTimerStart(uint32_t expTimeUsec) { PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_READY); PAL_TIMER_CHECK(expTimeUsec != 0); - uint32_t startTimeTick = PalTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec); + #if SCH_TIMER_REQUIRED == TRUE + #if BB_CLK_RATE_HZ == 32768 + uint32_t startTimeTick = palTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec); + + /* Set compare value to start BB. */ + PalRtcCompareSet(RTC_CHANNEL_START_BB, startTimeTick); + /* Enable RTC interrupt source to start BB. */ + PalRtcEnableCompareIrq(RTC_CHANNEL_START_BB); + + /* Set compare value to start HFCLK. */ - /* Clear pending events. */ - NRF_TIMER2->EVENTS_COMPARE[0] = 0; + uint32_t startHFCLKTick = (startTimeTick - PAL_HFCLK_OSC_SETTLE_TICKS) & PAL_MAX_RTC_COUNTER_VAL; - /* Set compare value. */ - NRF_TIMER2->CC[0] = startTimeTick; + PalRtcClearCompareEvents(RTC_CHANNEL_START_HFCLK); + PalRtcCompareSet(RTC_CHANNEL_START_HFCLK, startHFCLKTick); + #else + uint32_t startTimeTick = palTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec); - /* Enable TIMER2 interrupt source for CC[0]. */ - NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Msk; + /* Clear pending events. */ + NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; - palTimerCb.compareVal = startTimeTick; - palTimerCb.state = PAL_TIMER_STATE_BUSY; + /* Set compare value. */ + NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] = startTimeTick; + + /* Enable timer1 interrupt source for CC[0]. */ + NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Msk; + #endif + + palTimerCb.compareVal = startTimeTick; + palTimerCb.state = PAL_TIMER_STATE_BUSY; + #else + (void)expTimeUsec; + if (BbGetCurrentBod() == NULL) + { + SchLoadHandler(); + } + #endif } /*************************************************************************************************/ /*! * \brief Stop the scheduler timer. - * - * \return None */ /*************************************************************************************************/ void PalTimerStop() { - /* Disable this interrupt */ - NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; - - palTimerCb.state = PAL_TIMER_STATE_READY; + #if SCH_TIMER_REQUIRED == TRUE + #if BB_CLK_RATE_HZ == 32768 + /* Disable this interrupt */ + PalRtcDisableCompareIrq(RTC_CHANNEL_START_BB); + #else + /* Disable this interrupt */ + NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; + #endif + + palTimerCb.state = PAL_TIMER_STATE_READY; + #else + BbCancelBod(); + #endif } /*************************************************************************************************/ /*! - * \brief TIMER2 interrupt handler dedicated to scheduler timer. - * - * \return None. + * \brief TIMER1 interrupt handler dedicated to scheduler timer. */ /*************************************************************************************************/ -void TIMER2_IRQHandler_v(void) +void TIMER1_IRQHandler(void) { -#ifdef DEBUG - nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN); -#endif + #ifdef DEBUG + nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN); + #endif PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY); /* Check hardware status */ - PAL_TIMER_CHECK(NRF_TIMER2->EVENTS_COMPARE[0]); - PAL_TIMER_CHECK(NRF_TIMER2->CC[0] == palTimerCb.compareVal); - PAL_TIMER_CHECK(NRF_TIMER2->INTENSET == TIMER_INTENSET_COMPARE0_Msk); + PAL_TIMER_CHECK(NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB]); + PAL_TIMER_CHECK(NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] == palTimerCb.compareVal); + PAL_TIMER_CHECK(NRF_TIMER1->INTENSET == TIMER_INTENSET_COMPARE0_Msk); - /* Callback function could restart TIMER2. However, we blindly stop TIMER2 first. */ - NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; + /* Callback function could restart timer1. However, we blindly stop timer1 first. */ + NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; /* Clear event again just in case. */ - NRF_TIMER2->EVENTS_COMPARE[0] = 0; + NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; palTimerCb.state = PAL_TIMER_STATE_READY; @@ -245,7 +355,7 @@ void TIMER2_IRQHandler_v(void) palTimerCb.expCback(); } -#ifdef DEBUG - nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN); -#endif + #ifdef DEBUG + nrf_gpio_pin_clear(PAL_TIMER_DEBUG_0_PIN); + #endif } diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c index 5f30efd882f..7142877ff39 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c @@ -4,15 +4,14 @@ * * \brief TWI driver implementation. * - * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. - * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,11 +20,15 @@ */ /*************************************************************************************************/ -#include -#include "stack/platform/include/pal_twi.h" +#include "pal_twi.h" #include "nrfx_twim.h" #include "nrf_twim.h" #include "app_util_platform.h" +#include + +#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040) +#include "boards.h" +#endif /************************************************************************************************** Macros @@ -35,7 +38,7 @@ #ifndef PAL_TWI_MAX_DEVICE /*! \brief Maximum device count (must be an even multiple of 2^N). */ -#define PAL_TWI_MAX_DEVICE 4 +#define PAL_TWI_MAX_DEVICE 4 #endif /*! \brief Get next handle value, includes wrap around. */ @@ -44,10 +47,10 @@ #ifdef DEBUG /*! \brief Parameter check. */ -#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { twiDevCb.drvState = PAL_TWI_STATE_ERROR; return; } } +#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return; } } /*! \brief Parameter check, with return value. */ -#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { twiDevCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } } +#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } } #else @@ -62,12 +65,15 @@ /*! \brief TWI instance ID. */ #define PAL_TWI_INSTANCE_ID 0 -/*! \brief Pin number for SCL. */ -#define PAL_TWI_CLOCK_PIN_NUMBER (27U) - -/*! \brief Pin number for SDA. */ -#define PAL_TWI_DATA_PIN_NUMBER (26U) +#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040) +#define PAL_TWI_SCL_PIN ARDUINO_SCL_PIN /*!< Pin number for SCL. */ +#define PAL_TWI_SDA_PIN ARDUINO_SDA_PIN /*!< Pin number for SDA. */ +#endif +#if defined(BOARD_NRF6832) +#define PAL_TWI_SCL_PIN (6U) /*!< Pin number for SCL. */ +#define PAL_TWI_SDA_PIN (7U) /*!< Pin number for SDA. */ +#endif /************************************************************************************************** Type Definitions @@ -76,9 +82,9 @@ /*! \brief Commands state. */ typedef enum { - PAL_TWI_CMD_IDLE, /*!< Idle state. */ - PAL_TWI_CMD_TX_DATA, /*!< Write data state. */ - PAL_TWI_CMD_RX_DATA /*!< Read data state. */ + PAL_TWI_CMD_IDLE, /*!< Idle state. */ + PAL_TWI_CMD_TX_DATA, /*!< Write data state. */ + PAL_TWI_CMD_RX_DATA /*!< Read data state. */ } PalTwiCmdState_t; /*! \brief Device configuration. */ @@ -88,8 +94,6 @@ typedef struct PalTwiDevConfig_t devCfg; /*!< Device configuration. */ } PalTwiDevCtx_t; -#if NRFX_CHECK(NRFX_TWIM0_ENABLED) - /************************************************************************************************** Global Variables **************************************************************************************************/ @@ -98,10 +102,9 @@ typedef struct static struct { uint8_t curHandle; /*!< Current device handle. */ - PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */ - PalTwiState_t drvState; /*!< Current state. */ - bool_t firstCmd; /*!< First command after operation start flag. */ -} twiDevCb; + PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */ + PalTwiState_t drvState; /*!< Current state. */ +} palTwiCb = { 0 }; /*! \brief Device context table. */ static PalTwiDevCtx_t twiDevCtx[PAL_TWI_MAX_DEVICE]; @@ -113,10 +116,10 @@ static const nrfx_twim_t twiId = NRFX_TWIM_INSTANCE(PAL_TWI_INSTANCE_ID); const nrfx_twim_config_t twiConfig = { .frequency = NRF_TWIM_FREQ_400K, - .scl = PAL_TWI_CLOCK_PIN_NUMBER, - .sda = PAL_TWI_DATA_PIN_NUMBER, - .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, - .hold_bus_uninit = false + .scl = PAL_TWI_SCL_PIN, + .sda = PAL_TWI_SDA_PIN, + .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, // TODO define in common platform BSP + .hold_bus_uninit = FALSE }; /************************************************************************************************** @@ -125,59 +128,59 @@ const nrfx_twim_config_t twiConfig = /*************************************************************************************************/ /*! - * \brief Control callback. - * - * \param event Event parameters. + * \brief Operation complete callback. * - * \return None. + * \param pEvt Event parameters. + * \param pContext Unused context. */ /*************************************************************************************************/ -static void palTwiCallback(nrfx_twim_evt_t *event, void *pContext) +static void palTwiCallback(nrfx_twim_evt_t *pEvt, void *pCtx) { + (void)pCtx; + /* Pre-resolve device configuration. */ - PalTwiDevConfig_t *pCfg = &twiDevCtx[twiDevCb.curHandle].devCfg; + PalTwiDevConfig_t *pCfg = &twiDevCtx[palTwiCb.curHandle].devCfg; bool_t success = FALSE; - twiDevCb.firstCmd = FALSE; - - if ((event->type) == NRFX_TWIM_EVT_DONE) + if ((pEvt->type) == NRFX_TWIM_EVT_DONE) { success = TRUE; } - if (twiDevCb.cmdState == PAL_TWI_CMD_TX_DATA) + if (palTwiCb.cmdState == PAL_TWI_CMD_TX_DATA) { - twiDevCb.cmdState = PAL_TWI_CMD_IDLE; + palTwiCb.cmdState = PAL_TWI_CMD_IDLE; if (pCfg->wrCback) { - pCfg->wrCback(twiDevCb.curHandle, success); + pCfg->wrCback(palTwiCb.curHandle, success); } } - else if (twiDevCb.cmdState == PAL_TWI_CMD_RX_DATA) + else if (palTwiCb.cmdState == PAL_TWI_CMD_RX_DATA) { - twiDevCb.cmdState = PAL_TWI_CMD_IDLE; + palTwiCb.cmdState = PAL_TWI_CMD_IDLE; if (pCfg->rdCback) { - pCfg->rdCback(twiDevCb.curHandle, success); + pCfg->rdCback(palTwiCb.curHandle, success); } } + + palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND; } /*************************************************************************************************/ /*! * \brief Initialize TWI resources. - * - * \return None. */ /*************************************************************************************************/ void PalTwiInit(void) { - if (twiDevCb.drvState != PAL_TWI_STATE_UNINIT) + if (palTwiCb.drvState != PAL_TWI_STATE_UNINIT) { + /* Only initialize once. */ return; } - memset(&twiDevCb, 0, sizeof(twiDevCb)); + memset(&palTwiCb, 0, sizeof(palTwiCb)); for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) { @@ -187,24 +190,20 @@ void PalTwiInit(void) twiDevCtx[handle].devCfg.wrCback = NULL; } - twiDevCb.drvState = PAL_TWI_STATE_READY; + palTwiCb.drvState = PAL_TWI_STATE_READY; nrfx_twim_init(&twiId, &twiConfig, (nrfx_twim_evt_handler_t)palTwiCallback, NULL); nrfx_twim_enable(&twiId); - NVIC_ClearPendingIRQ(SPI0_TWI0_IRQn); - NVIC_EnableIRQ(SPI0_TWI0_IRQn); } /*************************************************************************************************/ /*! * \brief De-Initialize the TWI resources. - * - * \return None. */ /*************************************************************************************************/ void PalTwiDeInit(void) { - PAL_TWI_PARAM_CHECK(twiDevCb.drvState != PAL_TWI_STATE_BUSY); + PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_READY); for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) { @@ -214,10 +213,10 @@ void PalTwiDeInit(void) twiDevCtx[handle].devCfg.wrCback = NULL; } - nrfx_twim_uninit(&twiId); nrfx_twim_disable(&twiId); + nrfx_twim_uninit(&twiId); - twiDevCb.drvState = PAL_TWI_STATE_UNINIT; + palTwiCb.drvState = PAL_TWI_STATE_UNINIT; } /*************************************************************************************************/ @@ -232,7 +231,6 @@ void PalTwiDeInit(void) uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg) { PAL_TWI_PARAM_CHECK_RET(pDevCfg != NULL, PAL_TWI_INVALID_ID); - PAL_TWI_PARAM_CHECK_RET(pDevCfg->opReadyCback, PAL_TWI_INVALID_ID); uint8_t retValue = PAL_TWI_INVALID_ID; @@ -263,7 +261,7 @@ uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg) /*************************************************************************************************/ PalTwiState_t PalTwiGetState(void) { - return twiDevCb.drvState; + return palTwiCb.drvState; } /************************************************************************************************** @@ -275,28 +273,16 @@ PalTwiState_t PalTwiGetState(void) * \brief Always start an operation before reading or writing on TWI interface. * * \param handle Device handle. - * - * \return None. */ /*************************************************************************************************/ void PalTwiStartOperation(uint8_t handle) { PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - if (twiDevCb.drvState != PAL_TWI_STATE_READY) - { - PAL_TWI_PARAM_CHECK(handle != twiDevCb.curHandle); /* Client operation already in progress. */ - PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */ - } - - __disable_irq(); - - if (twiDevCb.drvState == PAL_TWI_STATE_READY) + if (palTwiCb.drvState == PAL_TWI_STATE_READY) { - __enable_irq(); - twiDevCb.drvState = PAL_TWI_STATE_BUSY; - twiDevCb.firstCmd = TRUE; - twiDevCb.curHandle = handle; + palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND; + palTwiCb.curHandle = handle; if (twiDevCtx[handle].devCfg.opReadyCback) { twiDevCtx[handle].devCfg.opReadyCback(handle); @@ -304,9 +290,11 @@ void PalTwiStartOperation(uint8_t handle) } else { + PAL_TWI_PARAM_CHECK(handle != palTwiCb.curHandle); /* Client operation already in progress. */ + PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */ + /* Pend the operation until current operation completes. */ twiDevCtx[handle].opPending = TRUE; - __enable_irq(); } } @@ -315,29 +303,18 @@ void PalTwiStartOperation(uint8_t handle) * \brief Always stop an operation after reading or writing on TWI interface. * * \param handle Device handle. - * - * \return None. */ /*************************************************************************************************/ void PalTwiStopOperation(uint8_t handle) { PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle); - PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE); - PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY); + PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); + PAL_TWI_PARAM_CHECK(palTwiCb.cmdState == PAL_TWI_CMD_IDLE); + PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_BUSY_DATA_PEND); unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle); - twiDevCb.curHandle = PAL_TWI_INVALID_ID; - - /* Only when address or command is sent, then issue stop. */ - if (!twiDevCb.firstCmd) - { - nrf_twim_event_clear(twiId.p_twim, NRF_TWIM_EVENT_STOPPED); - nrf_twim_task_trigger(twiId.p_twim, NRF_TWIM_TASK_RESUME); - nrf_twim_task_trigger(twiId.p_twim, NRF_TWIM_TASK_STOP); - nrf_twim_int_disable(twiId.p_twim, 0xFFFFFFFF); - } + palTwiCb.curHandle = PAL_TWI_INVALID_ID; while (nextHandle != handle) { @@ -346,13 +323,13 @@ void PalTwiStopOperation(uint8_t handle) /* Set the operation pending to FALSE first in case of race condition. */ twiDevCtx[nextHandle].opPending = FALSE; - twiDevCb.firstCmd = TRUE; - twiDevCb.curHandle = nextHandle; + palTwiCb.curHandle = nextHandle; if (twiDevCtx[nextHandle].devCfg.opReadyCback) { twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle); } + /* Remain in BUSY state. */ return; } @@ -360,64 +337,59 @@ void PalTwiStopOperation(uint8_t handle) } /* No pending operations. */ - twiDevCb.drvState = PAL_TWI_STATE_READY; + palTwiCb.drvState = PAL_TWI_STATE_READY; } /*************************************************************************************************/ /*! - * \brief Write data to TWI interface. + * \brief Read data from TWI interface. * * \param handle Device handle. - * \param pData Write buffer. + * \param pData Read buffer. * \param len Number of bytes to write. * - * \return None. - * - * Transfer \a len bytes from \a pData to the TWI device. + * Read \a len bytes from \a pData to the TWI device. */ /*************************************************************************************************/ -void PalTwiWriteData(uint8_t handle, const uint8_t *pData, uint8_t len) +void PalTwiReadData(uint8_t handle, uint8_t *pData, uint8_t len) { PAL_TWI_PARAM_CHECK(len != 0); PAL_TWI_PARAM_CHECK(pData != NULL); PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle); - PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY); - PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE); + PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); - twiDevCb.curHandle = handle; - twiDevCb.cmdState = PAL_TWI_CMD_TX_DATA; + palTwiCb.curHandle =handle; + palTwiCb.cmdState = PAL_TWI_CMD_RX_DATA; + palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER; - nrfx_twim_tx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len, NRFX_TWIM_FLAG_TX_NO_STOP); + nrfx_twim_rx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len); } /*************************************************************************************************/ /*! - * \brief Read data from TWI interface. + * \brief Write data to TWI interface. * * \param handle Device handle. * \param pData Write buffer. * \param len Number of bytes to write. * - * \return None. - * - * Read \a len bytes from \a pData to the TWI device. + * Transfer \a len bytes from \a pData to the TWI device. */ /*************************************************************************************************/ -void PalTwiReadData(uint8_t handle, uint8_t *pData, uint8_t len) +void PalTwiWriteData(uint8_t handle, const uint8_t *pData, uint8_t len) { PAL_TWI_PARAM_CHECK(len != 0); PAL_TWI_PARAM_CHECK(pData != NULL); PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == twiDevCb.curHandle); - PAL_TWI_PARAM_CHECK(twiDevCb.drvState == PAL_TWI_STATE_BUSY); - PAL_TWI_PARAM_CHECK(twiDevCb.cmdState == PAL_TWI_CMD_IDLE); + PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); - twiDevCb.curHandle =handle; - twiDevCb.cmdState = PAL_TWI_CMD_RX_DATA; + palTwiCb.curHandle = handle; + palTwiCb.cmdState = PAL_TWI_CMD_TX_DATA; + palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER; - nrfx_twim_rx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len); + nrfx_err_t err = nrfx_twim_tx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len, NRFX_TWIM_FLAG_TX_NO_STOP); + PAL_TWI_PARAM_CHECK(err == NRFX_SUCCESS); + #ifndef DEBUG + (void)err; + #endif } - -#endif // NRFX_CHECK(NRFX_TWIM0_ENABLED) - diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c index 5dbe1377935..f72feb801c6 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c @@ -4,15 +4,14 @@ * * \brief UART driver definition. * - * Copyright (c) 2018-2019 ARM Ltd. All Rights Reserved. - * ARM Ltd. confidential and proprietary. - * + * Copyright (c) 2019-2020 Packetcraft, Inc. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,237 +20,196 @@ */ /*************************************************************************************************/ -#include "stack/platform/include/pal_uart.h" -#include "sdk_config.h" +#include "pal_uart.h" #include "nrfx_uarte.h" + +#if defined(BOARD_NRF6832) +#define RX_PIN_NUMBER 26 +#define TX_PIN_NUMBER 27 +#define CTS_PIN_NUMBER 0xFF +#define RTS_PIN_NUMBER 0xFF +#else #include "boards.h" +#endif -#if NRFX_CHECK(NRFX_UARTE0_ENABLED) +/************************************************************************************************** + Type definitions +**************************************************************************************************/ + +/*! \brief Control block. */ +typedef struct +{ + PalUartState_t state; /*!< UART state. */ + PalUartConfig_t config; /*!< UART configuration. */ + nrfx_uarte_t inst; /*!< nRF UART driver instance. */ +} palUartCtrlBlk_t; /************************************************************************************************** Local Variables **************************************************************************************************/ -#define PAL_UART_INVALID_INSTANCE_NUM 0xFF + +#define PAL_UART_INVALID_INSTANCE_NUM 0xFF #ifdef DEBUG /*! \brief Parameter check. */ -#define PAL_UART_PARAM_CHECK(num, expr) { if (!(expr)) { palUartCb[num].state = PAL_UART_STATE_ERROR; while(1){}; } } +#define PAL_UART_PARAM_CHECK(p, expr) { if (!(expr)) { p->state = PAL_UART_STATE_ERROR; return; } } #else /*! \brief Parameter check (disabled). */ -#define PAL_UART_PARAM_CHECK(num, expr) +#define PAL_UART_PARAM_CHECK(p, expr) #endif /*! \brief Control block. */ -static struct -{ - PalUartId_t id; /*!< PAL UART id. */ - PalUartConfig_t config; /*!< PAL UART configuration. */ - PalUartState_t state; /*!< PAL UART state. */ - nrfx_uarte_t uart; /*!< NRF UART driver instance */ -} palUartCb[NRFX_UARTE0_ENABLED + NRFX_UARTE1_ENABLED] = {{0, {0}, 0, {NRF_UARTE0, NRFX_UARTE0_INST_IDX}}}; +static palUartCtrlBlk_t palUartCb[2]; /************************************************************************************************** Local Functions **************************************************************************************************/ + /*************************************************************************************************/ /*! * \brief Get UART instance number from UART ID. * - * \param uartId UART ID. + * \param id UART ID. * * \return UART instance number. */ /*************************************************************************************************/ -static uint8_t palUartGetNum(PalUartId_t uartId) +static palUartCtrlBlk_t *palUartGetContext(PalUartId_t id) { - uint8_t uartNum; - /* Nordic platform has total two UART instances. - * By default, only UART0 is enabled. - */ - switch (uartId) + switch (id) { case PAL_UART_ID_CHCI: - uartNum = 0; - break; case PAL_UART_ID_TERMINAL: - uartNum = 0; - break; - case PAL_UART_ID_USER: - uartNum = 0; - break; - - default: - uartNum = PAL_UART_INVALID_INSTANCE_NUM; - break; - } - - return uartNum; -} + return &palUartCb[0]; -/*************************************************************************************************/ -/*! - * \brief Set UART baud rate. - * - * \param baud Baud rate. - * - * \return nrf baud rate. - */ -/*************************************************************************************************/ -static nrf_uarte_baudrate_t palUartSetBaud(uint32_t baud) -{ - nrf_uarte_baudrate_t baudRate; + case PAL_UART_ID_USER: + return (NRFX_UARTE_ENABLED_COUNT > 1) ? &palUartCb[1] : &palUartCb[0]; - switch (baud) - { default: - case 115200: - baudRate = NRF_UARTE_BAUDRATE_115200; - break; - case 230400: - baudRate = NRF_UARTE_BAUDRATE_230400; - break; - case 460800: - baudRate = NRF_UARTE_BAUDRATE_460800; - break; - case 921600: - baudRate = NRF_UARTE_BAUDRATE_921600; - break; - case 1000000: - baudRate = NRF_UARTE_BAUDRATE_1000000; break; } - return baudRate; + return NULL; } /*************************************************************************************************/ /*! * \brief UART NRF event handler. * - * \param pEvent Pointer to event. - * \param pContext Pointer to event context. - * - * \return None. + * \param pEvent UART event. + * \param pContext Instance context. */ /*************************************************************************************************/ -static void palUartEventHandler(nrfx_uarte_event_t *pEvent, void *pContext) +static void palUartEventHandler(nrfx_uarte_event_t const *pEvent, void *pInstCtx) { - uint8_t uartNum = palUartGetNum(*(PalUartId_t *)pContext); + palUartCtrlBlk_t *pCtx = (palUartCtrlBlk_t *)pInstCtx; switch (pEvent->type) { case NRFX_UARTE_EVT_RX_DONE: - if (palUartCb[uartNum].config.rdCback != NULL) + if (pCtx->config.rdCback != NULL) { - palUartCb[uartNum].config.rdCback(); + pCtx->config.rdCback(); } break; case NRFX_UARTE_EVT_TX_DONE: - palUartCb[uartNum].state = PAL_UART_STATE_READY; - if (palUartCb[uartNum].config.wrCback != NULL) + pCtx->state = PAL_UART_STATE_READY; + if (pCtx->config.wrCback != NULL) { - palUartCb[uartNum].config.wrCback(); + pCtx->config.wrCback(); } break; case NRFX_UARTE_EVT_ERROR: - palUartCb[uartNum].state = PAL_UART_STATE_ERROR; + pCtx->state = PAL_UART_STATE_ERROR; break; default: break; } } -/************************************************************************************************** - Global Functions -**************************************************************************************************/ /*************************************************************************************************/ /*! * \brief Initialize UART. * - * \param id UART Id. - * \param pCfg Peripheral configuration. - * - * \return None. - * - * Initialize UART peripheral with \a pCfg values. + * \param id UART ID. + * \param pCfg Peripheral configuration. */ /*************************************************************************************************/ - void PalUartInit(PalUartId_t id, const PalUartConfig_t *pCfg) { - uint8_t uartNum = palUartGetNum(id); + palUartCtrlBlk_t *pCtx = palUartGetContext(id); + PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); + PAL_UART_PARAM_CHECK(pCtx, pCfg != NULL); + + pCtx->config = *pCfg; - if (uartNum == PAL_UART_INVALID_INSTANCE_NUM) + /* Resolve instance. */ + switch (pCtx - palUartCb) { - return; + default: + case 0: + pCtx->inst.p_reg = NRF_UARTE0; + pCtx->inst.drv_inst_idx = 0; + break; +#if (NRFX_UARTE1_ENABLED) + case 1: + pCtx->inst.p_reg = NRF_UARTE1; + pCtx->inst.drv_inst_idx = 1; + break; +#endif } - palUartCb[uartNum].id = id; - - PAL_UART_PARAM_CHECK(uartNum, pCfg != NULL); - - palUartCb[uartNum].config = *pCfg; - - /* Configure UART. */ - nrfx_uarte_config_t nrfConfig = NRFX_UARTE_DEFAULT_CONFIG; - nrfConfig.pselrxd = RX_PIN_NUMBER; - nrfConfig.pseltxd = TX_PIN_NUMBER; - nrfConfig.pselcts = CTS_PIN_NUMBER; - nrfConfig.pselrts = RTS_PIN_NUMBER; - nrfConfig.p_context = &(palUartCb[uartNum].id); - nrfConfig.parity = NRF_UARTE_PARITY_EXCLUDED; - nrfConfig.interrupt_priority = 0xFF; /* Lowest priority. */ - - nrfConfig.baudrate = palUartSetBaud(pCfg->baud); - nrfConfig.hwfc = pCfg->hwFlow ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED; - - /* Make sure UART is uninitialized. */ - nrfx_uarte_uninit(&(palUartCb[uartNum].uart)); - - /* Initialize UART. */ - nrfx_err_t err_code = nrfx_uarte_init(&(palUartCb[uartNum].uart), &nrfConfig, (nrfx_uarte_event_handler_t)palUartEventHandler); + nrfx_uarte_config_t nrfCfg = NRFX_UARTE_DEFAULT_CONFIG; + nrfCfg.pselrxd = RX_PIN_NUMBER; + nrfCfg.pseltxd = TX_PIN_NUMBER; + nrfCfg.pselcts = CTS_PIN_NUMBER; + nrfCfg.pselrts = RTS_PIN_NUMBER; + nrfCfg.p_context = pCtx; + nrfCfg.parity = NRF_UARTE_PARITY_EXCLUDED; + nrfCfg.interrupt_priority = 0xFF; /* Lowest priority. */ + nrfCfg.hwfc = pCfg->hwFlow ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED; + + switch (pCfg->baud) + { + default: + case 115200: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_115200; break; + case 230400: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_230400; break; + case 460800: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_460800; break; + case 921600: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_921600; break; + case 1000000: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_1000000; break; + } - //this is for uart only not for uarte - //nrfx_uart_rx_enable(&palUartCb[uartNum].uart); + nrfx_err_t err_code = nrfx_uarte_init(&(pCtx->inst), &nrfCfg, palUartEventHandler); if (err_code != NRFX_SUCCESS) { - palUartCb[uartNum].state = PAL_UART_STATE_ERROR; + pCtx->state = PAL_UART_STATE_ERROR; return; } - palUartCb[uartNum].state = PAL_UART_STATE_READY; - - NVIC_EnableIRQ(UART0_IRQn); + pCtx->state = PAL_UART_STATE_READY; } /*************************************************************************************************/ /*! * \brief De-Initialize UART. * - * \param id UART id. - * - * \return None. - * - * De-Initialize UART. + * \param id UART ID. */ /*************************************************************************************************/ void PalUartDeInit(PalUartId_t id) { - uint8_t uartNum = palUartGetNum(id); + palUartCtrlBlk_t *pCtx = palUartGetContext(id); + PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); + PAL_UART_PARAM_CHECK(pCtx, pCtx->state == PAL_UART_STATE_READY); - if (uartNum == PAL_UART_INVALID_INSTANCE_NUM) - { - return; - } - - nrfx_uarte_uninit(&(palUartCb[uartNum].uart)); + nrfx_uarte_uninit(&pCtx->inst); - palUartCb[uartNum].state = PAL_UART_STATE_UNINIT; + pCtx->state = PAL_UART_STATE_UNINIT; } /*************************************************************************************************/ @@ -260,81 +218,62 @@ void PalUartDeInit(PalUartId_t id) * * \param id UART id. * -* \return Current state. - * - * Return the current state. + * \return Current state. */ /*************************************************************************************************/ PalUartState_t PalUartGetState(PalUartId_t id) { - uint8_t uartNum = palUartGetNum(id); + palUartCtrlBlk_t *pCtx = palUartGetContext(id); - if (uartNum == PAL_UART_INVALID_INSTANCE_NUM) + if (pCtx == NULL) { return PAL_UART_STATE_ERROR; } - return palUartCb[uartNum].state; + return pCtx->state; } /*************************************************************************************************/ /*! * \brief Read data from Rx FIFO. * - * \param id UART id. - * \param pData Read buffer. - * \param len Number of bytes to read. - * - * \return None. - * - * Store \a len received bytes in \a pData. After \a len is transferred, call - * \a UartInitInfo_t::rdCback to signal read completion. Alway call this function to setup buffer - * when boot up or after a reading is done + * \param id UART ID. + * \param pData Read buffer. + * \param len Number of bytes to read. */ /*************************************************************************************************/ void PalUartReadData(PalUartId_t id, uint8_t *pData, uint16_t len) { - uint8_t uartNum = palUartGetNum(id); - - PAL_UART_PARAM_CHECK(uartNum, pData != NULL); - PAL_UART_PARAM_CHECK(uartNum, len > 0); - PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state != PAL_UART_STATE_UNINIT); - - if (uartNum == PAL_UART_INVALID_INSTANCE_NUM) - { - return; - } - nrfx_uarte_rx(&(palUartCb[uartNum].uart), pData, (uint16_t)len); + palUartCtrlBlk_t *pCtx = palUartGetContext(id); + PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); + PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT); + PAL_UART_PARAM_CHECK(pCtx, pData != NULL); + PAL_UART_PARAM_CHECK(pCtx, len > 0); + + nrfx_err_t err = nrfx_uarte_rx(&pCtx->inst, pData, len); + PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS); + (void)err; } /*************************************************************************************************/ /*! * \brief Write data to Tx FIFO. * - * \param id UART id. - * \param pData Write buffer. - * \param len Number of bytes to write. - * - * \return None. - * - * Assign buffer and length and transmit data. + * \param id UART ID. + * \param pData Write buffer. + * \param len Number of bytes to write. */ /*************************************************************************************************/ void PalUartWriteData(PalUartId_t id, const uint8_t *pData, uint16_t len) { - uint8_t uartNum = palUartGetNum(id); - - PAL_UART_PARAM_CHECK(uartNum, pData != NULL); - PAL_UART_PARAM_CHECK(uartNum, len > 0); - PAL_UART_PARAM_CHECK(uartNum, palUartCb[uartNum].state == PAL_UART_STATE_READY); - - if (uartNum == PAL_UART_INVALID_INSTANCE_NUM) - { - return; - } - - nrfx_uarte_tx(&(palUartCb[uartNum].uart), pData, (uint16_t)len); - palUartCb[uartNum].state = PAL_UART_STATE_BUSY; + palUartCtrlBlk_t *pCtx = palUartGetContext(id); + PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); + PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT); + PAL_UART_PARAM_CHECK(pCtx, pData != NULL); + PAL_UART_PARAM_CHECK(pCtx, len > 0); + + pCtx->state = PAL_UART_STATE_BUSY; + nrfx_err_t err = nrfx_uarte_tx(&pCtx->inst, pData, len); + PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS); + (void)err; } - -#endif // NRFX_CHECK(NRFX_UARTE0_ENABLED) From a04102ae39970653a44af3d3b31549098f6f719a Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 13:16:44 +0100 Subject: [PATCH 23/38] switch to timer 2 due to conflict --- .../TARGET_NRF5x/stack/sources/pal_timer.c | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c index c2ec5f834d3..eeb7befa0ef 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c @@ -162,10 +162,10 @@ static uint32_t palTimerGetCurrentTime(void) /* Read and return the captured count value from capture register 1 */ return PalRtcCounterGet(); #else - /* Capture current TIMER1 count to capture register 1 */ - NRF_TIMER1->TASKS_CAPTURE[TIMER_CHANNEL_READ_TICK] = 1; + /* Capture current TIMER2 count to capture register 1 */ + NRF_TIMER2->TASKS_CAPTURE[TIMER_CHANNEL_READ_TICK] = 1; /* Read and return the captured count value from capture register 1 */ - return NRF_TIMER1->CC[TIMER_CHANNEL_READ_TICK]; + return NRF_TIMER2->CC[TIMER_CHANNEL_READ_TICK]; #endif } return 0; @@ -192,28 +192,28 @@ void PalTimerInit(PalTimerCompCback_t expCback) PalRtcIrqRegister(RTC_CHANNEL_START_BB, palTimerRtcIrqHandler); #else /* Give scheduler timer the highest priority. */ - NVIC_SetPriority(TIMER1_IRQn, 0); /* highest priority */ - NVIC_DisableIRQ(TIMER1_IRQn); + NVIC_SetPriority(TIMER2_IRQn, 0); /* highest priority */ + NVIC_DisableIRQ(TIMER2_IRQn); /* stop timer if it was somehow running (timer must be stopped for configuration) */ - NRF_TIMER1->TASKS_STOP = 1; + NRF_TIMER2->TASKS_STOP = 1; /* clear timer to zero count */ - NRF_TIMER1->TASKS_CLEAR = 1; + NRF_TIMER2->TASKS_CLEAR = 1; /* configure timer */ - NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer; - NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit; - NRF_TIMER1->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */ + NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer; + NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + NRF_TIMER2->PRESCALER = PAL_TIMER_1MHZ_PRESCALER; /* f = 16MHz / (2 ^ TIMER_PRESCALER) */ /* timer1 is a free running clock. */ - NRF_TIMER1->TASKS_START = 1; + NRF_TIMER2->TASKS_START = 1; /* Clear out and enable timer1 interrupt at system level. */ - NRF_TIMER1->INTENCLR = 0xFFFFFFFF; - NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; - NVIC_ClearPendingIRQ(TIMER1_IRQn); - NVIC_EnableIRQ(TIMER1_IRQn); + NRF_TIMER2->INTENCLR = 0xFFFFFFFF; + NRF_TIMER2->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; + NVIC_ClearPendingIRQ(TIMER2_IRQn); + NVIC_EnableIRQ(TIMER2_IRQn); #endif #endif @@ -231,10 +231,10 @@ void PalTimerDeInit(void) { #if SCH_TIMER_REQUIRED == TRUE #if BB_CLK_RATE_HZ != 32768 - NVIC_DisableIRQ(TIMER1_IRQn); + NVIC_DisableIRQ(TIMER2_IRQn); /* stop timer */ - NRF_TIMER1->TASKS_STOP = 1; + NRF_TIMER2->TASKS_STOP = 1; #endif #endif @@ -284,13 +284,13 @@ void PalTimerStart(uint32_t expTimeUsec) uint32_t startTimeTick = palTimerGetCurrentTime() + PAL_TIMER_US_TO_TICKS(expTimeUsec); /* Clear pending events. */ - NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; + NRF_TIMER2->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; /* Set compare value. */ - NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] = startTimeTick; + NRF_TIMER2->CC[TIMER_CHANNEL_START_BB] = startTimeTick; /* Enable timer1 interrupt source for CC[0]. */ - NRF_TIMER1->INTENSET = TIMER_INTENSET_COMPARE0_Msk; + NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE0_Msk; #endif palTimerCb.compareVal = startTimeTick; @@ -317,7 +317,7 @@ void PalTimerStop() PalRtcDisableCompareIrq(RTC_CHANNEL_START_BB); #else /* Disable this interrupt */ - NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; + NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; #endif palTimerCb.state = PAL_TIMER_STATE_READY; @@ -328,10 +328,10 @@ void PalTimerStop() /*************************************************************************************************/ /*! - * \brief TIMER1 interrupt handler dedicated to scheduler timer. + * \brief TIMER2 interrupt handler dedicated to scheduler timer. */ /*************************************************************************************************/ -void TIMER1_IRQHandler(void) +void TIMER2_IRQHandler(void) { #ifdef DEBUG nrf_gpio_pin_set(PAL_TIMER_DEBUG_0_PIN); @@ -339,14 +339,14 @@ void TIMER1_IRQHandler(void) PAL_TIMER_CHECK(palTimerCb.state == PAL_TIMER_STATE_BUSY); /* Check hardware status */ - PAL_TIMER_CHECK(NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB]); - PAL_TIMER_CHECK(NRF_TIMER1->CC[TIMER_CHANNEL_START_BB] == palTimerCb.compareVal); - PAL_TIMER_CHECK(NRF_TIMER1->INTENSET == TIMER_INTENSET_COMPARE0_Msk); + PAL_TIMER_CHECK(NRF_TIMER2->EVENTS_COMPARE[TIMER_CHANNEL_START_BB]); + PAL_TIMER_CHECK(NRF_TIMER2->CC[TIMER_CHANNEL_START_BB] == palTimerCb.compareVal); + PAL_TIMER_CHECK(NRF_TIMER2->INTENSET == TIMER_INTENSET_COMPARE0_Msk); /* Callback function could restart timer1. However, we blindly stop timer1 first. */ - NRF_TIMER1->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; + NRF_TIMER2->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk; /* Clear event again just in case. */ - NRF_TIMER1->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; + NRF_TIMER2->EVENTS_COMPARE[TIMER_CHANNEL_START_BB] = 0; palTimerCb.state = PAL_TIMER_STATE_READY; From d9699cf269cdf2813f0a5ac03cd47f8ab3ec4835 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 16:20:14 +0100 Subject: [PATCH 24/38] asm only for gcc --- .../TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h index d580bf44a8c..e1219610f6c 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/thirdparty/uecc/uECC_ll.h @@ -29,7 +29,11 @@ uECC_asm_fast - Use GCC inline assembly optimized for maximum speed. */ #define uECC_asm_small 1 #define uECC_asm_fast 2 #ifndef uECC_ASM - #define uECC_ASM uECC_asm_fast + #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__) && defined(__GNUC__) /* Only support GCC inline asm for now */ + #define uECC_ASM uECC_asm_fast + #else + #define uECC_ASM uECC_asm_none + #endif #endif /* Curve selection options. */ From ebd4aed9b14062b46e07ed4cae1e5352980f301a Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Wed, 10 Jun 2020 16:20:22 +0100 Subject: [PATCH 25/38] disable led --- .../TARGET_NRF5x/stack/sources/pal_sys.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c index ccbd06dd58d..445c67db629 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c @@ -158,10 +158,6 @@ void PalSysInit(void) PalRtcInit(); - PalLedInit(); - PalLedOff(PAL_LED_ID_ERROR); - PalLedOn(PAL_LED_ID_CPU_ACTIVE); - #ifdef DEBUG /* Reset free memory. */ memset(SystemHeapStart, 0, SystemHeapSize); @@ -175,7 +171,6 @@ void PalSysInit(void) /*************************************************************************************************/ void PalSysAssertTrap(void) { - PalLedOn(PAL_LED_ID_ERROR); palSysAssertCount++; From dbd58bfd02bb9eea90c0e08f6cc7044d41708ffb Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:21:45 +0100 Subject: [PATCH 26/38] remove unneeded pal --- .../pal_mbed_os_adaptation.cpp | 15 + .../TARGET_NRF5x/stack/sources/pal_led.c | 273 ------------ .../TARGET_NRF5x/stack/sources/pal_nvm.c | 357 ---------------- .../TARGET_NRF5x/stack/sources/pal_rtc.c | 260 ------------ .../TARGET_NRF5x/stack/sources/pal_sys.c | 311 -------------- .../TARGET_NRF5x/stack/sources/pal_twi.c | 395 ------------------ .../TARGET_NRF5x/stack/sources/pal_uart.c | 279 ------------- 7 files changed, 15 insertions(+), 1875 deletions(-) delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_nvm.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c delete mode 100644 features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp index fa2f10e3d1a..922982ca9a0 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp @@ -113,6 +113,21 @@ MBED_WEAK void PalSysSleep() MBED_ERROR(function_not_implemented, "Provide implementation of PalSysSleep"); } +MBED_WEAK void PalSysSetTrap(bool_t enable) +{ + (void)enable; +} + +MBED_WEAK uint32_t PalSysGetAssertCount() +{ + return 0; +} + +MBED_WEAK uint32_t PalSysGetStackUsage() +{ + return 0; +} + /* CS */ MBED_WEAK void PalEnterCs(void) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c deleted file mode 100644 index c114b632625..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_led.c +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief LED driver implementation. - * - * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include "pal_led.h" - -#if defined(BOARD_PCA10056) -#include "boards.h" -#include "nrfx_gpiote.h" -#endif - -#if defined(BOARD_NRF6832) -#include "lp5562.h" -#endif - -/************************************************************************************************** - Functions: Initialization -**************************************************************************************************/ - -#if defined(BOARD_NRF6832) -/*************************************************************************************************/ -/*! - * \brief Map LED ID to physical LED. - * - * \param ledId LED ID. - * - * \return Mapped physical LED. - */ -/*************************************************************************************************/ -static int palLedMapId(uint8_t ledId) -{ - switch (ledId) - { - /* Predefined */ - case PAL_LED_ID_ERROR: - return LP5562_LED_W; /* bottom */ - break; - - /* Application defined */ - case 0: - return LP5562_LED_R; /* top/left */ - case 1: - return LP5562_LED_G; /* top/middle */ - case 2: - return LP5562_LED_B; /* top/right */ - - /* Ignore */ - case PAL_LED_ID_CPU_ACTIVE: - default: - break; - } - - return -1; -} -#endif - -/*************************************************************************************************/ -/*! - * \brief Initialize LEDs. - */ -/*************************************************************************************************/ -void PalLedInit(void) -{ -#if defined(BOARD_PCA10056) - nrfx_err_t err; - - if (!nrfx_gpiote_is_init()) - { - err = nrfx_gpiote_init(); - - if (err != NRFX_SUCCESS) - { - return; - } - } - - nrfx_gpiote_out_config_t cfg = NRFX_GPIOTE_CONFIG_OUT_SIMPLE(true); - - nrfx_gpiote_out_init(LED_1, &cfg); - nrfx_gpiote_out_init(LED_2, &cfg); - nrfx_gpiote_out_init(LED_3, &cfg); - nrfx_gpiote_out_init(LED_4, &cfg); -#endif - -#if AUDIO_CAPE - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 1), &cfg); - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 2), &cfg); - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 3), &cfg); - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 4), &cfg); - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 5), &cfg); - nrfx_gpiote_out_init(NRF_GPIO_PIN_MAP(1, 6), &cfg); -#endif - -#if defined(BOARD_NRF6832) - lp5562_LedInit(); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief De-initialize LEDs. - */ -/*************************************************************************************************/ -void PalLedDeInit(void) -{ -#if defined(BOARD_PCA10056) - nrfx_gpiote_out_uninit(LED_1); - nrfx_gpiote_out_uninit(LED_2); - nrfx_gpiote_out_uninit(LED_3); - nrfx_gpiote_out_uninit(LED_4); -#endif - -#if defined(BOARD_NRF6832) - lp5562_LedDeInit(); -#endif - -#if AUDIO_CAPE - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 1)); - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 2)); - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 3)); - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 4)); - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 5)); - nrfx_gpiote_out_uninit(NRF_GPIO_PIN_MAP(1, 6)); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Set LED on. - * - * \param ledId LED ID. - */ -/*************************************************************************************************/ -void PalLedOn(uint8_t ledId) -{ -#if defined(BOARD_PCA10056) - switch (ledId) - { - case PAL_LED_ID_CPU_ACTIVE: - nrfx_gpiote_out_clear(LED_2); - break; - case PAL_LED_ID_ERROR: - nrfx_gpiote_out_clear(LED_4); - break; - case 0: - nrfx_gpiote_out_clear(LED_1); - break; - case 1: - nrfx_gpiote_out_clear(LED_3); - break; - default: - break; - } -#endif - -#if defined(BOARD_NRF6832) - int ledPin = palLedMapId(ledId); - if (ledPin >= 0) - { - lp5562_LedOn(ledPin); - } -#endif - -#if AUDIO_CAPE - switch (ledId) - { - case 2: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 1)); - break; - case 3: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 2)); - break; - case 4: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 3)); - break; - case 5: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 4)); - break; - case 6: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 5)); - break; - case 7: - nrfx_gpiote_out_clear(NRF_GPIO_PIN_MAP(1, 6)); - break; - default: - break; - } -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Set LED off. - * - * \param ledId LED ID. - */ -/*************************************************************************************************/ -void PalLedOff(uint8_t ledId) -{ -#if defined(BOARD_PCA10056) - switch (ledId) - { - case PAL_LED_ID_CPU_ACTIVE: - nrfx_gpiote_out_set(LED_2); - break; - case PAL_LED_ID_ERROR: - nrfx_gpiote_out_set(LED_4); - break; - case 0: - nrfx_gpiote_out_set(LED_1); - break; - case 1: - nrfx_gpiote_out_set(LED_3); - break; - default: - break; - } -#endif - -#if defined(BOARD_NRF6832) - int ledPin = palLedMapId(ledId); - if (ledPin >= 0) - { - lp5562_LedOff(ledPin); - } -#endif - -#if AUDIO_CAPE - switch (ledId) - { - case 2: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 1)); - break; - case 3: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 2)); - break; - case 4: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 3)); - break; - case 5: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 4)); - break; - case 6: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 5)); - break; - case 7: - nrfx_gpiote_out_set(NRF_GPIO_PIN_MAP(1, 6)); - break; - default: - break; - } -#endif -} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_nvm.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_nvm.c deleted file mode 100644 index 4baca509674..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_nvm.c +++ /dev/null @@ -1,357 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief PAL NVM driver. - * - * Copyright (c) 2018-2019 Arm Ltd. All Rights Reserved. - * Arm Ltd. confidential and proprietary. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include -#include "stack/platform/include/pal_nvm.h" -#include "sdk_config.h" -#if defined(NRF52840_XXAA) -#include "nrfx_qspi.h" -#include "boards.h" -#endif - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/*! NVM block size. */ -#define PAL_NVM_SECTOR64K_SIZE 0x10000 - -/*! NVM internal cache buffer size. Note: should be at least 2. */ -#define PAL_NVM_CACHE_BUF_SIZE 11 - -/*! Aligns a value to word size. */ -#define PAL_NVM_WORD_ALIGN(value) (((value) + (PAL_NVM_WORD_SIZE - 1)) & \ - ~(PAL_NVM_WORD_SIZE - 1)) -/*! Validates if a value is aligned to word. */ -#define PAL_NVM_IS_WORD_ALIGNED(value) (((uint32_t)(value) & \ - (PAL_NVM_WORD_SIZE - 1)) == 0) - -/*! QSPI flash commands. */ -#define QSPI_STD_CMD_WRSR 0x01 -#define QSPI_STD_CMD_RSTEN 0x66 -#define QSPI_STD_CMD_RST 0x99 - -#ifdef DEBUG - -/*! \brief Parameter check. */ -#define PAL_NVM_PARAM_CHECK(expr) { \ - if (!(expr)) \ - { \ - palNvmCb.state = PAL_NVM_STATE_ERROR; \ - return; \ - } \ - } - -#else - -/*! \brief Parameter check (disabled). */ -#define PAL_NVM_PARAM_CHECK(expr) - -#endif - -/************************************************************************************************** - Local Variables -**************************************************************************************************/ - -/*! NVM cache buffer. */ -static uint32_t palNvmCacheBuf[PAL_NVM_CACHE_BUF_SIZE]; - -/*! \brief Control block. */ -struct -{ - PalNvmState_t state; /*!< State. */ - uint32_t writeAddr; /*!< Write address. */ -} palNvmCb; - -/************************************************************************************************** - Global Functions -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Initialize the platform NVM. - * - * \param[in] actCback Callback function. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmInit(PalNvmCback_t actCback) -{ -#if defined(NRF52840_XXAA) - - uint32_t status; - uint8_t temp = 0x40; - - nrfx_qspi_config_t config = - { \ - .xip_offset = NRFX_QSPI_CONFIG_XIP_OFFSET, \ - .pins = { \ - .sck_pin = BSP_QSPI_SCK_PIN, \ - .csn_pin = BSP_QSPI_CSN_PIN, \ - .io0_pin = BSP_QSPI_IO0_PIN, \ - .io1_pin = BSP_QSPI_IO1_PIN, \ - .io2_pin = BSP_QSPI_IO2_PIN, \ - .io3_pin = BSP_QSPI_IO3_PIN, \ - }, \ - .irq_priority = (uint8_t)NRFX_QSPI_CONFIG_IRQ_PRIORITY, \ - .prot_if = { \ - .readoc = (nrf_qspi_readoc_t)NRFX_QSPI_CONFIG_READOC, \ - .writeoc = (nrf_qspi_writeoc_t)NRFX_QSPI_CONFIG_WRITEOC, \ - .addrmode = (nrf_qspi_addrmode_t)NRFX_QSPI_CONFIG_ADDRMODE, \ - .dpmconfig = false, \ - }, \ - .phy_if = { \ - .sck_freq = (nrf_qspi_frequency_t)NRFX_QSPI_CONFIG_FREQUENCY, \ - .sck_delay = (uint8_t)NRFX_QSPI_CONFIG_SCK_DELAY, \ - .spi_mode = (nrf_qspi_spi_mode_t)NRFX_QSPI_CONFIG_MODE, \ - .dpmen = false \ - }, \ - } - ; - - /* Verify palNvmCacheBuf size is at least 2. */ - PAL_NVM_PARAM_CHECK(PAL_NVM_CACHE_BUF_SIZE >= 2); - - status = nrfx_qspi_init(&config, NULL, NULL); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - nrf_qspi_cinstr_conf_t cinstr_cfg = { - .opcode = QSPI_STD_CMD_RSTEN, - .length = NRF_QSPI_CINSTR_LEN_1B, - .io2_level = 1, - .io3_level = 1, - .wipwait = 1, - .wren = 1 - }; - - /* Send reset enable. */ - status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); - - /* Send reset command */ - cinstr_cfg.opcode = QSPI_STD_CMD_RST; - - status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - /* Switch to qspi mode */ - cinstr_cfg.opcode = QSPI_STD_CMD_WRSR; - cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_2B; - - status = nrfx_qspi_cinstr_xfer(&cinstr_cfg, &temp, NULL); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - memset(&palNvmCb, 0, sizeof(palNvmCb)); - - palNvmCb.state = PAL_NVM_STATE_READY; - - (void)status; -#else - (void)palNvmCacheBuf; -#endif -} - -/*************************************************************************************************/ -/*! - * \brief De-initialize the platform NVM. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmDeInit(void) -{ -#if defined(NRF52840_XXAA) - nrfx_qspi_uninit(); -#else -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Reads data from NVM storage. - * - * \param[in] pBuf Pointer to memory buffer where data will be stored. - * \param[in] size Data size in bytes to be read. - * \param[in] srcAddr Word aligned address from where data is read. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmRead(void *pBuf, uint32_t size, uint32_t srcAddr) -{ -#if defined(NRF52840_XXAA) - uint32_t readSize = PAL_NVM_WORD_ALIGN(size); - uint32_t actualSize = size; - uint32_t status; - uint16_t addrOffset = 0; - - PAL_NVM_PARAM_CHECK(palNvmCb.state == PAL_NVM_STATE_READY); - PAL_NVM_PARAM_CHECK(pBuf != NULL); - PAL_NVM_PARAM_CHECK(size != 0); - - do - { - if (readSize <= sizeof(palNvmCacheBuf)) - { - /* Read data. */ - status = nrfx_qspi_read(palNvmCacheBuf, readSize, srcAddr + addrOffset); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - memcpy((uint8_t*)pBuf + addrOffset, palNvmCacheBuf, actualSize); - - readSize = 0; - } - else - { - /* Read data. */ - status = nrfx_qspi_read(palNvmCacheBuf, sizeof(palNvmCacheBuf), srcAddr + addrOffset); - - PAL_NVM_PARAM_CHECK (status == NRFX_SUCCESS); - - memcpy((uint8_t*)pBuf + addrOffset, palNvmCacheBuf, sizeof(palNvmCacheBuf)); - - addrOffset += sizeof(palNvmCacheBuf); - readSize -= sizeof(palNvmCacheBuf); - actualSize -= sizeof(palNvmCacheBuf); - } - } while (readSize != 0); - (void)status; -#else - memset(pBuf, 0xFF, size); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Writes data to NVM storage. - * - * \param[in] pBuf Pointer to memory buffer from where data will be written. - * \param[in] size Data size in bytes to be written. - * \param[in] dstAddr Word aligned address to write data. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmWrite(void *pBuf, uint32_t size, uint32_t dstAddr) -{ -#if defined(NRF52840_XXAA) - uint32_t writeSize = PAL_NVM_WORD_ALIGN(size); - uint32_t actualSize = size; - uint32_t status; - uint16_t addrOffset = 0; - - PAL_NVM_PARAM_CHECK(palNvmCb.state == PAL_NVM_STATE_READY); - PAL_NVM_PARAM_CHECK(pBuf != NULL); - PAL_NVM_PARAM_CHECK(size != 0); - - do - { - if (writeSize <= sizeof(palNvmCacheBuf)) - { - memcpy(palNvmCacheBuf, (uint8_t*)pBuf + addrOffset, actualSize); - memset((uint8_t*)palNvmCacheBuf + actualSize, 0xFF, sizeof(palNvmCacheBuf) - actualSize); - - /* Write data. */ - status = nrfx_qspi_write(palNvmCacheBuf, writeSize, dstAddr + addrOffset); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - writeSize = 0; - } - else - { - memcpy(palNvmCacheBuf, (uint8_t*)pBuf + addrOffset, sizeof(palNvmCacheBuf)); - - /* Write data. */ - status = nrfx_qspi_write(palNvmCacheBuf, sizeof(palNvmCacheBuf), dstAddr + addrOffset); - - PAL_NVM_PARAM_CHECK(status == NRFX_SUCCESS); - - addrOffset += sizeof(palNvmCacheBuf); - writeSize -= sizeof(palNvmCacheBuf); - actualSize -= sizeof(palNvmCacheBuf); - } - } while (writeSize != 0); - (void)status; -#else -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Erase sector. - * - * \param[in] size Data size in bytes to be erased. - * \param[in] startAddr Word aligned address. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmEraseSector(uint32_t size, uint32_t startAddr) -{ -#if defined(NRF52840_XXAA) - nrf_qspi_erase_len_t eSize = QSPI_ERASE_LEN_LEN_4KB; - - if (size > PAL_NVM_SECTOR_SIZE) - { - eSize = QSPI_ERASE_LEN_LEN_64KB; - } - - if (size > PAL_NVM_SECTOR64K_SIZE) - { - eSize = QSPI_ERASE_LEN_LEN_All; - } - - nrfx_qspi_erase(eSize, startAddr); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Erase chip. It is not recommended to use since it takes up to 240s. - * - * \return None. - */ -/*************************************************************************************************/ -void PalNvmEraseChip(void) -{ -#if defined(NRF52840_XXAA) - nrfx_qspi_chip_erase(); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief Get NVM state. - * - * \return NVM state. - */ -/*************************************************************************************************/ -PalNvmState_t PalNvmGetState(void) -{ - return palNvmCb.state; -} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c deleted file mode 100644 index 084485e0197..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_rtc.c +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief Tickless timer implementation. - * - * Copyright (c) 2013-2018 Arm Ltd. All Rights Reserved. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Notes: - * - * This is timer driver is used by wsf_timer.c and pal_timer.c. - * - */ -/*************************************************************************************************/ - -#include "nrf.h" -#include "pal_rtc.h" -#include "pal_timer.h" - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#ifdef DEBUG - -/*! \brief Parameter and state check. */ -#define PAL_RTC_CHECK(expr) { if (!(expr)) { while(1); } } - -#else - -/*! \brief Parameter and state check (disabled). */ -#define PAL_RTC_CHECK(expr) - -#endif - -#define RTC_TIMER_TOTAL_CHANNEL 4 - -/************************************************************************************************** - Variables -**************************************************************************************************/ - -static palRtcIrqCback_t palRtcTimerCback[RTC_TIMER_TOTAL_CHANNEL]; - -/*************************************************************************************************/ -/*! - * \brief Function for clearing rtc events. - * - * \param channelId Channel ID Number. - */ -/*************************************************************************************************/ -void PalRtcClearCompareEvents(uint8_t channelId) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - - NRF_RTC1->EVENTS_COMPARE[channelId] = 0; - (void)NRF_RTC1->EVENTS_COMPARE[channelId]; -} - -/*************************************************************************************************/ -/*! - * \brief Function for starting the RTC timer. - * - * \param channelId Channel ID Number. - */ -/*************************************************************************************************/ -void PalRtcEnableCompareIrq(uint8_t channelId) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - - PalRtcClearCompareEvents(channelId); - - switch (channelId) - { - case 0: - NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; - NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk; - break; - case 1: - NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE1_Msk; - NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE1_Msk; - break; - case 2: - NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE2_Msk; - NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE2_Msk; - break; - case 3: - NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE3_Msk; - NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE3_Msk; - break; - default: - break; - } -} - -/*************************************************************************************************/ -/*! - * \brief Function for stopping the RTC timer. - * - * \param channelId Channel ID Number. - */ -/*************************************************************************************************/ -void PalRtcDisableCompareIrq(uint8_t channelId) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - - switch (channelId) - { - case 0: - NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE0_Msk; - NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE0_Msk; - break; - case 1: - NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE1_Msk; - NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE1_Msk; - break; - case 2: - NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE2_Msk; - NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE2_Msk; - break; - case 3: - NRF_RTC1->INTENCLR = RTC_INTENCLR_COMPARE3_Msk; - NRF_RTC1->EVTENCLR = RTC_EVTENCLR_COMPARE3_Msk; - break; - default: - break; - } -} - -/*************************************************************************************************/ -/*! - * \brief Get the current value of the RTC counter. - * - * \return Current value of the RTC counter. - */ -/*************************************************************************************************/ -uint32_t PalRtcCounterGet(void) -{ - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {} - NRF_RTC1->TASKS_STOP = 0; - - return NRF_RTC1->COUNTER; -} - -/*************************************************************************************************/ -/*! - * \brief Set the RTC capture compare value. - * - * \param channelId Channel ID Number. - * \param value Set new value for compare value. - */ -/*************************************************************************************************/ -void PalRtcCompareSet(uint8_t channelId, uint32_t value) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - NRF_RTC1->CC[channelId] = value; -} - -/*************************************************************************************************/ -/*! - * \brief Get the current value of the RTC capture compare. - * - * \param channelId Channel ID Number. - * - * \return Current value of the capture compare. - */ -/*************************************************************************************************/ -uint32_t PalRtcCompareGet(uint8_t channelId) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - return NRF_RTC1->CC[channelId]; -} - -/*************************************************************************************************/ -/*! - * \brief RTC interrupt handler. - * - * This handler stores the RTC start time which is used as a reference to compute the receive - * packet timestamp using the HFCLK. - * - */ -/*************************************************************************************************/ -void RTC1_IRQHandler(void) -{ - for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++) - { - if (NRF_RTC1->EVENTS_COMPARE[channelId]) - { - PalRtcClearCompareEvents(channelId); - - if (palRtcTimerCback[channelId]) - { - palRtcTimerCback[channelId](); - } - } - } -} - -/*************************************************************************************************/ -/*! - * \brief Tickless timer initialization routine. - */ -/*************************************************************************************************/ -void PalRtcInit(void) -{ - /* Stop RTC to prevent any running timers from expiring. */ - for (unsigned int channelId = 0; channelId < RTC_TIMER_TOTAL_CHANNEL; channelId++) - { - PalRtcDisableCompareIrq(channelId); - } - - /* Configure low-frequency clock. */ - NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); - - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) { } - NRF_RTC1->TASKS_STOP = 0; - - NRF_RTC1->TASKS_STOP = 1; - NRF_RTC1->TASKS_CLEAR = 1; - NRF_RTC1->PRESCALER = 0; /* clear prescaler */ - NRF_RTC1->TASKS_START = 1; - - NVIC_SetPriority(RTC1_IRQn, 0x80); /* medium priority */ - NVIC_ClearPendingIRQ(RTC1_IRQn); - NVIC_EnableIRQ(RTC1_IRQn); -} - -/*************************************************************************************************/ -/*! - * \brief Register rtc IRQ callback. - * - * \param channelId Channel ID Number. - * \param cback Call back for ISR. - * - * This callback is dedicated for scheduler timer in low power code. - * - */ -/*************************************************************************************************/ -void PalRtcIrqRegister(uint8_t channelId, palRtcIrqCback_t cback) -{ - PAL_RTC_CHECK(channelId < RTC_TIMER_TOTAL_CHANNEL); - palRtcTimerCback[channelId] = cback; -} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c deleted file mode 100644 index 445c67db629..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_sys.c +++ /dev/null @@ -1,311 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief System hooks. - * - * Copyright (c) 2013-2019 Arm Ltd. All Rights Reserved. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include "nrf.h" -#include "pal_rtc.h" -#include "pal_sys.h" -#include "pal_led.h" -#include "pal_timer.h" -#include "pal_bb.h" -#include "pal_uart.h" - -#include - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -#ifdef __GNUC__ - -/*! \brief Stack initial values. */ -#define INIT_STACK_VAL 0xAFAFAFAF - -/*! \brief Starting memory location of free memory. */ -#define FREE_MEM_START ((uint8_t *)&__heap_start__) - -/*! \brief Total size in bytes of free memory. */ -#define FREE_MEM_SIZE ((uint32_t)&__heap_end__ - (uint32_t)&__heap_start__) - -extern uint8_t *SystemHeapStart; -extern uint32_t SystemHeapSize; - -extern unsigned long __text_end__; -extern unsigned long __data_start__; -extern unsigned long __data_end__; -extern unsigned long __bss_start__; -extern unsigned long __bss_end__; -extern unsigned long __stack_top__; -extern unsigned long __stack_limit__; -extern unsigned long __heap_end__; -extern unsigned long __heap_start__; - -#else - -/*! \brief Starting memory location of free memory. */ -#define FREE_MEM_START ((uint8_t *)palSysFreeMem) - -/*! \brief Total size in bytes of free memory. */ -#define FREE_MEM_SIZE (1024 * 196) - -#endif - -/************************************************************************************************** - Global Variables -**************************************************************************************************/ - -#ifdef __GNUC__ - -uint8_t *SystemHeapStart; -uint32_t SystemHeapSize; - -#else - -/*! \brief Free memory for pool buffers (align to word boundary). */ -uint32_t palSysFreeMem[FREE_MEM_SIZE/sizeof(uint32_t)]; - -uint8_t *SystemHeapStart = (uint8_t *) palSysFreeMem; -uint32_t SystemHeapSize = FREE_MEM_SIZE; - -#endif - -/*! \brief Number of assertions. */ -static uint32_t palSysAssertCount; - -/*! \brief Trap enabled flag. */ -static volatile bool_t PalSysAssertTrapEnable; - -static uint32_t palSysBusyCount; - -/************************************************************************************************** - Functions -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Enter a critical section. - */ -/*************************************************************************************************/ -void PalEnterCs(void) -{ - #ifdef __IAR_SYSTEMS_ICC__ - __disable_interrupt(); - #endif - #ifdef __GNUC__ - __asm volatile ("cpsid i"); - #endif - #ifdef __CC_ARM - __disable_irq(); - #endif -} - -/*************************************************************************************************/ -/*! - * \brief Exit a critical section. - */ -/*************************************************************************************************/ -void PalExitCs(void) -{ - #ifdef __IAR_SYSTEMS_ICC__ - __enable_interrupt(); - #endif - #ifdef __GNUC__ - __asm volatile ("cpsie i"); - #endif - #ifdef __CC_ARM - __enable_irq(); - #endif -} - -/*************************************************************************************************/ -/*! - * \brief Common platform initialization. - */ -/*************************************************************************************************/ -void PalSysInit(void) -{ - /* Enable Flash cache */ - NRF_NVMC->ICACHECNF |= (NVMC_ICACHECNF_CACHEEN_Enabled << NVMC_ICACHECNF_CACHEEN_Pos); - - /* Use 16 MHz crystal oscillator (system starts up using 16MHz RC oscillator). */ - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - NRF_CLOCK->TASKS_HFCLKSTART = 1; - while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) { } - - palSysAssertCount = 0; - PalSysAssertTrapEnable = TRUE; - palSysBusyCount = 0; - - PalRtcInit(); - -#ifdef DEBUG - /* Reset free memory. */ - memset(SystemHeapStart, 0, SystemHeapSize); -#endif -} - -/*************************************************************************************************/ -/*! - * \brief System fault trap. - */ -/*************************************************************************************************/ -void PalSysAssertTrap(void) -{ - - palSysAssertCount++; - - while (PalSysAssertTrapEnable); -} - -/*************************************************************************************************/ -/*! - * \brief Set system trap. - * - * \param enable Enable assert trap or not. - */ -/*************************************************************************************************/ -void PalSysSetTrap(bool_t enable) -{ - PalSysAssertTrapEnable = enable; -} - -/*************************************************************************************************/ -/*! - * \brief Get assert count. - */ -/*************************************************************************************************/ -uint32_t PalSysGetAssertCount(void) -{ - return palSysAssertCount; -} - -/*************************************************************************************************/ -/*! - * \brief Count stack usage. - * - * \return Number of bytes used by the stack. - */ -/*************************************************************************************************/ -uint32_t PalSysGetStackUsage(void) -{ -#ifdef __GNUC__ - unsigned long *pUnused = &__stack_limit__; - - while (pUnused < &__stack_top__) - { - if (*pUnused != INIT_STACK_VAL) - { - break; - } - - pUnused++; - } - - return (uint32_t)(&__stack_top__ - pUnused) * sizeof(*pUnused); -#else - /* Not available; stub routine. */ - return 0; -#endif -} - -/*************************************************************************************************/ -/*! - * \brief System sleep. - */ -/*************************************************************************************************/ -void PalSysSleep(void) -{ - /* Clock management for low power mode. */ - #if BB_CLK_RATE_HZ == 32768 - uint32_t rtcNow = NRF_RTC1->COUNTER; - - if ((BbGetCurrentBod() == NULL) && PalUartGetState(PAL_UART_ID_CHCI) == PAL_UART_STATE_UNINIT) - { - if ((PalTimerGetState() == PAL_TIMER_STATE_BUSY && - ((NRF_RTC1->CC[3] - rtcNow) & PAL_MAX_RTC_COUNTER_VAL) > PAL_HFCLK_OSC_SETTLE_TICKS) || - (PalTimerGetState() == PAL_TIMER_STATE_READY)) - { - /* disable HFCLK */ - NRF_CLOCK->TASKS_HFCLKSTOP = 1; - NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; - (void)NRF_CLOCK->EVENTS_HFCLKSTARTED; - } - } - #endif - - /* CPU sleep. */ - #ifdef __IAR_SYSTEMS_ICC__ - __wait_for_interrupt(); - #endif - #ifdef __GNUC__ - __asm volatile ("wfi"); - #endif - #ifdef __CC_ARM - __wfi(); - #endif -} - -/*************************************************************************************************/ -/*! - * \brief Check if system is busy. - * - * \return TRUE if system is busy. - */ -/*************************************************************************************************/ -bool_t PalSysIsBusy(void) -{ - bool_t sysIsBusy = FALSE; - PalEnterCs(); - sysIsBusy = ((palSysBusyCount == 0) ? FALSE : TRUE); - PalExitCs(); - return sysIsBusy; -} - -/*************************************************************************************************/ -/*! - * \brief Set system busy. - * - * \return none. - */ -/*************************************************************************************************/ -void PalSysSetBusy(void) -{ - PalEnterCs(); - palSysBusyCount++; - PalExitCs(); -} - -/*************************************************************************************************/ -/*! - * \brief Set system idle. - */ -/*************************************************************************************************/ -void PalSysSetIdle(void) -{ - PalEnterCs(); - if (palSysBusyCount) - { - palSysBusyCount--; - } - PalExitCs(); -} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c deleted file mode 100644 index 7142877ff39..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_twi.c +++ /dev/null @@ -1,395 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief TWI driver implementation. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include "pal_twi.h" -#include "nrfx_twim.h" -#include "nrf_twim.h" -#include "app_util_platform.h" -#include - -#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040) -#include "boards.h" -#endif - -/************************************************************************************************** - Macros -**************************************************************************************************/ - -/* Allow compiler directive override. */ -#ifndef PAL_TWI_MAX_DEVICE - -/*! \brief Maximum device count (must be an even multiple of 2^N). */ -#define PAL_TWI_MAX_DEVICE 4 -#endif - -/*! \brief Get next handle value, includes wrap around. */ -#define PAL_TWI_GET_NEXT_HANDLE(h) (((h) + 1) & (PAL_TWI_MAX_DEVICE - 1)) - -#ifdef DEBUG - -/*! \brief Parameter check. */ -#define PAL_TWI_PARAM_CHECK(expr) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return; } } - -/*! \brief Parameter check, with return value. */ -#define PAL_TWI_PARAM_CHECK_RET(expr, rv) { if (!(expr)) { palTwiCb.drvState = PAL_TWI_STATE_ERROR; return (rv); } } - -#else - -/*! \brief Parameter check (disabled). */ -#define PAL_TWI_PARAM_CHECK(expr) - -/*! \brief Parameter check, with return value (disabled). */ -#define PAL_TWI_PARAM_CHECK_RET(expr, rv) - -#endif - -/*! \brief TWI instance ID. */ -#define PAL_TWI_INSTANCE_ID 0 - -#if defined(BOARD_PCA10056) | defined(BOARD_PCA10040) -#define PAL_TWI_SCL_PIN ARDUINO_SCL_PIN /*!< Pin number for SCL. */ -#define PAL_TWI_SDA_PIN ARDUINO_SDA_PIN /*!< Pin number for SDA. */ -#endif - -#if defined(BOARD_NRF6832) -#define PAL_TWI_SCL_PIN (6U) /*!< Pin number for SCL. */ -#define PAL_TWI_SDA_PIN (7U) /*!< Pin number for SDA. */ -#endif - -/************************************************************************************************** - Type Definitions -**************************************************************************************************/ - -/*! \brief Commands state. */ -typedef enum -{ - PAL_TWI_CMD_IDLE, /*!< Idle state. */ - PAL_TWI_CMD_TX_DATA, /*!< Write data state. */ - PAL_TWI_CMD_RX_DATA /*!< Read data state. */ -} PalTwiCmdState_t; - -/*! \brief Device configuration. */ -typedef struct -{ - bool_t opPending; /*!< Operation pending flag. */ - PalTwiDevConfig_t devCfg; /*!< Device configuration. */ -} PalTwiDevCtx_t; - -/************************************************************************************************** - Global Variables -**************************************************************************************************/ - -/*! \brief Driver control block. */ -static struct -{ - uint8_t curHandle; /*!< Current device handle. */ - PalTwiCmdState_t cmdState; /*!< Command transaction state, Tx or Rx. */ - PalTwiState_t drvState; /*!< Current state. */ -} palTwiCb = { 0 }; - -/*! \brief Device context table. */ -static PalTwiDevCtx_t twiDevCtx[PAL_TWI_MAX_DEVICE]; - -/*! \brief TWI instance. */ -static const nrfx_twim_t twiId = NRFX_TWIM_INSTANCE(PAL_TWI_INSTANCE_ID); - -/*! \brief TWI config. */ -const nrfx_twim_config_t twiConfig = -{ - .frequency = NRF_TWIM_FREQ_400K, - .scl = PAL_TWI_SCL_PIN, - .sda = PAL_TWI_SDA_PIN, - .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, // TODO define in common platform BSP - .hold_bus_uninit = FALSE -}; - -/************************************************************************************************** - Functions: Initialization -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Operation complete callback. - * - * \param pEvt Event parameters. - * \param pContext Unused context. - */ -/*************************************************************************************************/ -static void palTwiCallback(nrfx_twim_evt_t *pEvt, void *pCtx) -{ - (void)pCtx; - - /* Pre-resolve device configuration. */ - PalTwiDevConfig_t *pCfg = &twiDevCtx[palTwiCb.curHandle].devCfg; - bool_t success = FALSE; - - if ((pEvt->type) == NRFX_TWIM_EVT_DONE) - { - success = TRUE; - } - - if (palTwiCb.cmdState == PAL_TWI_CMD_TX_DATA) - { - palTwiCb.cmdState = PAL_TWI_CMD_IDLE; - if (pCfg->wrCback) - { - pCfg->wrCback(palTwiCb.curHandle, success); - } - } - else if (palTwiCb.cmdState == PAL_TWI_CMD_RX_DATA) - { - palTwiCb.cmdState = PAL_TWI_CMD_IDLE; - if (pCfg->rdCback) - { - pCfg->rdCback(palTwiCb.curHandle, success); - } - } - - palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND; -} - -/*************************************************************************************************/ -/*! - * \brief Initialize TWI resources. - */ -/*************************************************************************************************/ -void PalTwiInit(void) -{ - if (palTwiCb.drvState != PAL_TWI_STATE_UNINIT) - { - /* Only initialize once. */ - return; - } - - memset(&palTwiCb, 0, sizeof(palTwiCb)); - - for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) - { - twiDevCtx[handle].devCfg.devAddr = PAL_TWI_INVALID_ID; - twiDevCtx[handle].devCfg.opReadyCback = NULL; - twiDevCtx[handle].devCfg.rdCback = NULL; - twiDevCtx[handle].devCfg.wrCback = NULL; - } - - palTwiCb.drvState = PAL_TWI_STATE_READY; - - nrfx_twim_init(&twiId, &twiConfig, (nrfx_twim_evt_handler_t)palTwiCallback, NULL); - nrfx_twim_enable(&twiId); -} - -/*************************************************************************************************/ -/*! - * \brief De-Initialize the TWI resources. - */ -/*************************************************************************************************/ -void PalTwiDeInit(void) -{ - PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_READY); - - for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) - { - twiDevCtx[handle].devCfg.devAddr = PAL_TWI_INVALID_ID; - twiDevCtx[handle].devCfg.opReadyCback = NULL; - twiDevCtx[handle].devCfg.rdCback = NULL; - twiDevCtx[handle].devCfg.wrCback = NULL; - } - - nrfx_twim_disable(&twiId); - nrfx_twim_uninit(&twiId); - - palTwiCb.drvState = PAL_TWI_STATE_UNINIT; -} - -/*************************************************************************************************/ -/*! - * \brief Register a device on the TWI bus. - * - * \param pDevCfg Device configuration. - * - * \return Device handle. - */ -/*************************************************************************************************/ -uint8_t PalTwiRegisterDevice(PalTwiDevConfig_t *pDevCfg) -{ - PAL_TWI_PARAM_CHECK_RET(pDevCfg != NULL, PAL_TWI_INVALID_ID); - - uint8_t retValue = PAL_TWI_INVALID_ID; - - for (unsigned int handle = 0; handle < PAL_TWI_MAX_DEVICE; handle++) - { - if ((twiDevCtx[handle].devCfg.devAddr == PAL_TWI_INVALID_ID) && (pDevCfg->devAddr != PAL_TWI_INVALID_ID)) - { - twiDevCtx[handle].devCfg = *pDevCfg; - return (uint8_t)handle; - } - } - - return retValue; -} - -/************************************************************************************************** - Functions: Control and Status -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Get the current state. - * - * \return Current state. - * - * Return the current state of the TWI. - */ -/*************************************************************************************************/ -PalTwiState_t PalTwiGetState(void) -{ - return palTwiCb.drvState; -} - -/************************************************************************************************** - Functions: Data Transfer -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Always start an operation before reading or writing on TWI interface. - * - * \param handle Device handle. - */ -/*************************************************************************************************/ -void PalTwiStartOperation(uint8_t handle) -{ - PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - - if (palTwiCb.drvState == PAL_TWI_STATE_READY) - { - palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_PEND; - palTwiCb.curHandle = handle; - if (twiDevCtx[handle].devCfg.opReadyCback) - { - twiDevCtx[handle].devCfg.opReadyCback(handle); - } - } - else - { - PAL_TWI_PARAM_CHECK(handle != palTwiCb.curHandle); /* Client operation already in progress. */ - PAL_TWI_PARAM_CHECK(twiDevCtx[handle].opPending == FALSE); /* Client already pended an operation. */ - - /* Pend the operation until current operation completes. */ - twiDevCtx[handle].opPending = TRUE; - } -} - -/*************************************************************************************************/ -/*! - * \brief Always stop an operation after reading or writing on TWI interface. - * - * \param handle Device handle. - */ -/*************************************************************************************************/ -void PalTwiStopOperation(uint8_t handle) -{ - PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); - PAL_TWI_PARAM_CHECK(palTwiCb.cmdState == PAL_TWI_CMD_IDLE); - PAL_TWI_PARAM_CHECK(palTwiCb.drvState == PAL_TWI_STATE_BUSY_DATA_PEND); - - unsigned int nextHandle = PAL_TWI_GET_NEXT_HANDLE(handle); - - palTwiCb.curHandle = PAL_TWI_INVALID_ID; - - while (nextHandle != handle) - { - if (twiDevCtx[nextHandle].opPending) - { - /* Set the operation pending to FALSE first in case of race condition. */ - twiDevCtx[nextHandle].opPending = FALSE; - - palTwiCb.curHandle = nextHandle; - if (twiDevCtx[nextHandle].devCfg.opReadyCback) - { - twiDevCtx[nextHandle].devCfg.opReadyCback(nextHandle); - } - - /* Remain in BUSY state. */ - return; - } - - nextHandle = PAL_TWI_GET_NEXT_HANDLE(nextHandle); - } - - /* No pending operations. */ - palTwiCb.drvState = PAL_TWI_STATE_READY; -} - -/*************************************************************************************************/ -/*! - * \brief Read data from TWI interface. - * - * \param handle Device handle. - * \param pData Read buffer. - * \param len Number of bytes to write. - * - * Read \a len bytes from \a pData to the TWI device. - */ -/*************************************************************************************************/ -void PalTwiReadData(uint8_t handle, uint8_t *pData, uint8_t len) -{ - PAL_TWI_PARAM_CHECK(len != 0); - PAL_TWI_PARAM_CHECK(pData != NULL); - PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); - - palTwiCb.curHandle =handle; - palTwiCb.cmdState = PAL_TWI_CMD_RX_DATA; - palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER; - - nrfx_twim_rx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len); -} - -/*************************************************************************************************/ -/*! - * \brief Write data to TWI interface. - * - * \param handle Device handle. - * \param pData Write buffer. - * \param len Number of bytes to write. - * - * Transfer \a len bytes from \a pData to the TWI device. - */ -/*************************************************************************************************/ -void PalTwiWriteData(uint8_t handle, const uint8_t *pData, uint8_t len) -{ - PAL_TWI_PARAM_CHECK(len != 0); - PAL_TWI_PARAM_CHECK(pData != NULL); - PAL_TWI_PARAM_CHECK(handle < PAL_TWI_MAX_DEVICE); - PAL_TWI_PARAM_CHECK(handle == palTwiCb.curHandle); - - palTwiCb.curHandle = handle; - palTwiCb.cmdState = PAL_TWI_CMD_TX_DATA; - palTwiCb.drvState = PAL_TWI_STATE_BUSY_DATA_XFER; - - nrfx_err_t err = nrfx_twim_tx(&twiId, twiDevCtx[handle].devCfg.devAddr, pData, len, NRFX_TWIM_FLAG_TX_NO_STOP); - PAL_TWI_PARAM_CHECK(err == NRFX_SUCCESS); - #ifndef DEBUG - (void)err; - #endif -} diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c deleted file mode 100644 index f72feb801c6..00000000000 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_uart.c +++ /dev/null @@ -1,279 +0,0 @@ -/*************************************************************************************************/ -/*! - * \file - * - * \brief UART driver definition. - * - * Copyright (c) 2019-2020 Packetcraft, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*************************************************************************************************/ - -#include "pal_uart.h" -#include "nrfx_uarte.h" - -#if defined(BOARD_NRF6832) -#define RX_PIN_NUMBER 26 -#define TX_PIN_NUMBER 27 -#define CTS_PIN_NUMBER 0xFF -#define RTS_PIN_NUMBER 0xFF -#else -#include "boards.h" -#endif - -/************************************************************************************************** - Type definitions -**************************************************************************************************/ - -/*! \brief Control block. */ -typedef struct -{ - PalUartState_t state; /*!< UART state. */ - PalUartConfig_t config; /*!< UART configuration. */ - nrfx_uarte_t inst; /*!< nRF UART driver instance. */ -} palUartCtrlBlk_t; - -/************************************************************************************************** - Local Variables -**************************************************************************************************/ - -#define PAL_UART_INVALID_INSTANCE_NUM 0xFF - -#ifdef DEBUG - -/*! \brief Parameter check. */ -#define PAL_UART_PARAM_CHECK(p, expr) { if (!(expr)) { p->state = PAL_UART_STATE_ERROR; return; } } - -#else - -/*! \brief Parameter check (disabled). */ -#define PAL_UART_PARAM_CHECK(p, expr) - -#endif - -/*! \brief Control block. */ -static palUartCtrlBlk_t palUartCb[2]; - -/************************************************************************************************** - Local Functions -**************************************************************************************************/ - -/*************************************************************************************************/ -/*! - * \brief Get UART instance number from UART ID. - * - * \param id UART ID. - * - * \return UART instance number. - */ -/*************************************************************************************************/ -static palUartCtrlBlk_t *palUartGetContext(PalUartId_t id) -{ - switch (id) - { - case PAL_UART_ID_CHCI: - case PAL_UART_ID_TERMINAL: - return &palUartCb[0]; - - case PAL_UART_ID_USER: - return (NRFX_UARTE_ENABLED_COUNT > 1) ? &palUartCb[1] : &palUartCb[0]; - - default: - break; - } - - return NULL; -} - -/*************************************************************************************************/ -/*! - * \brief UART NRF event handler. - * - * \param pEvent UART event. - * \param pContext Instance context. - */ -/*************************************************************************************************/ -static void palUartEventHandler(nrfx_uarte_event_t const *pEvent, void *pInstCtx) -{ - palUartCtrlBlk_t *pCtx = (palUartCtrlBlk_t *)pInstCtx; - - switch (pEvent->type) - { - case NRFX_UARTE_EVT_RX_DONE: - if (pCtx->config.rdCback != NULL) - { - pCtx->config.rdCback(); - } - break; - case NRFX_UARTE_EVT_TX_DONE: - pCtx->state = PAL_UART_STATE_READY; - if (pCtx->config.wrCback != NULL) - { - pCtx->config.wrCback(); - } - break; - case NRFX_UARTE_EVT_ERROR: - pCtx->state = PAL_UART_STATE_ERROR; - break; - default: - break; - } -} - -/*************************************************************************************************/ -/*! - * \brief Initialize UART. - * - * \param id UART ID. - * \param pCfg Peripheral configuration. - */ -/*************************************************************************************************/ -void PalUartInit(PalUartId_t id, const PalUartConfig_t *pCfg) -{ - palUartCtrlBlk_t *pCtx = palUartGetContext(id); - PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); - PAL_UART_PARAM_CHECK(pCtx, pCfg != NULL); - - pCtx->config = *pCfg; - - /* Resolve instance. */ - switch (pCtx - palUartCb) - { - default: - case 0: - pCtx->inst.p_reg = NRF_UARTE0; - pCtx->inst.drv_inst_idx = 0; - break; -#if (NRFX_UARTE1_ENABLED) - case 1: - pCtx->inst.p_reg = NRF_UARTE1; - pCtx->inst.drv_inst_idx = 1; - break; -#endif - } - - nrfx_uarte_config_t nrfCfg = NRFX_UARTE_DEFAULT_CONFIG; - nrfCfg.pselrxd = RX_PIN_NUMBER; - nrfCfg.pseltxd = TX_PIN_NUMBER; - nrfCfg.pselcts = CTS_PIN_NUMBER; - nrfCfg.pselrts = RTS_PIN_NUMBER; - nrfCfg.p_context = pCtx; - nrfCfg.parity = NRF_UARTE_PARITY_EXCLUDED; - nrfCfg.interrupt_priority = 0xFF; /* Lowest priority. */ - nrfCfg.hwfc = pCfg->hwFlow ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED; - - switch (pCfg->baud) - { - default: - case 115200: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_115200; break; - case 230400: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_230400; break; - case 460800: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_460800; break; - case 921600: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_921600; break; - case 1000000: nrfCfg.baudrate = NRF_UARTE_BAUDRATE_1000000; break; - } - - nrfx_err_t err_code = nrfx_uarte_init(&(pCtx->inst), &nrfCfg, palUartEventHandler); - - if (err_code != NRFX_SUCCESS) - { - pCtx->state = PAL_UART_STATE_ERROR; - return; - } - - pCtx->state = PAL_UART_STATE_READY; -} - -/*************************************************************************************************/ -/*! - * \brief De-Initialize UART. - * - * \param id UART ID. - */ -/*************************************************************************************************/ -void PalUartDeInit(PalUartId_t id) -{ - palUartCtrlBlk_t *pCtx = palUartGetContext(id); - PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); - PAL_UART_PARAM_CHECK(pCtx, pCtx->state == PAL_UART_STATE_READY); - - nrfx_uarte_uninit(&pCtx->inst); - - pCtx->state = PAL_UART_STATE_UNINIT; -} - -/*************************************************************************************************/ -/*! - * \brief Get the current state. - * - * \param id UART id. - * - * \return Current state. - */ -/*************************************************************************************************/ -PalUartState_t PalUartGetState(PalUartId_t id) -{ - palUartCtrlBlk_t *pCtx = palUartGetContext(id); - - if (pCtx == NULL) - { - return PAL_UART_STATE_ERROR; - } - - return pCtx->state; -} - -/*************************************************************************************************/ -/*! - * \brief Read data from Rx FIFO. - * - * \param id UART ID. - * \param pData Read buffer. - * \param len Number of bytes to read. - */ -/*************************************************************************************************/ -void PalUartReadData(PalUartId_t id, uint8_t *pData, uint16_t len) -{ - palUartCtrlBlk_t *pCtx = palUartGetContext(id); - PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); - PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT); - PAL_UART_PARAM_CHECK(pCtx, pData != NULL); - PAL_UART_PARAM_CHECK(pCtx, len > 0); - - nrfx_err_t err = nrfx_uarte_rx(&pCtx->inst, pData, len); - PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS); - (void)err; -} - -/*************************************************************************************************/ -/*! - * \brief Write data to Tx FIFO. - * - * \param id UART ID. - * \param pData Write buffer. - * \param len Number of bytes to write. - */ -/*************************************************************************************************/ -void PalUartWriteData(PalUartId_t id, const uint8_t *pData, uint16_t len) -{ - palUartCtrlBlk_t *pCtx = palUartGetContext(id); - PAL_UART_PARAM_CHECK(pCtx, pCtx != NULL); - PAL_UART_PARAM_CHECK(pCtx, pCtx->state != PAL_UART_STATE_UNINIT); - PAL_UART_PARAM_CHECK(pCtx, pData != NULL); - PAL_UART_PARAM_CHECK(pCtx, len > 0); - - pCtx->state = PAL_UART_STATE_BUSY; - nrfx_err_t err = nrfx_uarte_tx(&pCtx->inst, pData, len); - PAL_UART_PARAM_CHECK(pCtx, err == NRFX_SUCCESS); - (void)err; -} From 3a46d09a874ee1b37f22d6adcf7620263b158826 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:22:40 +0100 Subject: [PATCH 27/38] add stubs for iso channels, update config for iso --- .../pal_mbed_os_adaptation.cpp | 56 +++++++++++++++++++ .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 11 +++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp index 922982ca9a0..f1843cc62f1 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack_adaptation/pal_mbed_os_adaptation.cpp @@ -19,6 +19,7 @@ #include "stack/platform/include/pal_uart.h" #include "hal/ticker_api.h" #include "mbed_critical.h" +#include "pal_codec.h" #ifdef __cplusplus extern "C" { @@ -139,6 +140,61 @@ MBED_WEAK void PalExitCs(void) core_util_critical_section_exit(); } +/* ISO channels */ + +MBED_WEAK void PalCodecReadLocalSupportedCodecs(uint8_t *pNumStd, AudioStdCodecInfo_t stdCodecs[], + uint8_t *pNumVs, AudioVsCodecInfo_t vsCodecs[]) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecReadLocalSupportedCodecs"); +} + +MBED_WEAK bool_t PalCodecReadLocalSupportedCodecCapabilities( + uint8_t codingFmt, uint16_t compId, uint16_t vsCodecId, PalAudioDir_t dir) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecReadLocalSupportedCodecCapabilities"); + return 0; +} + +MBED_WEAK bool_t PalCodecReadLocalSupportedControllerDelay( + uint8_t codingFmt, uint16_t compId, uint16_t vsCodecId, PalAudioDir_t dir, uint32_t *pMinDly, uint32_t *pMaxDly) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecReadLocalSupportedControllerDelay"); + return 0; +} +MBED_WEAK bool_t PalCodecConfigureDataPath(PalAudioDir_t dir, uint8_t dataPathId) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecConfigureDataPath"); + return 0; +} + +MBED_WEAK void PalCodecDataInit(void) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecDataInit"); +} + +MBED_WEAK bool_t PalCodecDataStartStream(uint16_t id, PalCodecSreamParam_t *pParam) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecDataStartStream"); + return 0; +} + +MBED_WEAK void PalCodecDataStopStream(uint16_t id) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecDataStopStream"); +} + +MBED_WEAK uint16_t PalCodecDataStreamIn(uint16_t id, uint8_t *pBuf, uint16_t len, uint32_t *pPktCtr) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecDataStreamIn"); + return 0; +} + +MBED_WEAK void PalCodecDataStreamOut(uint16_t id, const uint8_t *pBuf, uint16_t len, uint32_t pktCtr) +{ + MBED_ERROR(function_not_implemented, "Provide implementation of PalCodecDataStreamOut"); +} + + #ifdef __cplusplus }; #endif diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index b06d2a08f6d..9db5da1e274 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -154,7 +154,7 @@ const LlRtCfg_t NRFCordioHCIDriver::_ll_cfg = { /** Default number of ISO receive buffers. */ /*uint8_t*/ .numIsoRxBuf = 0, /** Maximum ISO buffer size between host and controller. */ -/*uint16_t*/ .maxIsoBufLen = 0, +/*uint16_t*/ .maxIsoSduLen = 0, /** Maximum ISO PDU buffer size. */ /*uint16_t*/ .maxIsoPduLen = 0, @@ -164,7 +164,14 @@ const LlRtCfg_t NRFCordioHCIDriver::_ll_cfg = { /** Maximum number of CIS. */ /*uint8_t*/ .maxCis = 0, /** Subevent spacing above T_MSS. */ -/*uint16_t*/ .subEvtSpaceDelay = 0, +/*uint16_t*/ .cisSubEvtSpaceDelay = 0, + +/* BIS */ +/** Maximum number of BIG. */ +/* uint8_t */ .maxBig = 0, +/** Maximum number of BIS. */ +/* uint8_t */ .maxBis = 0, + /* DTM */ /** DTM Rx synchronization window in milliseconds. */ /*uint16_t*/ .dtmRxSyncMs = 10000, From 16cbc97feb3d889244fb5e67ced1c6e1cca0e5a4 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:23:10 +0100 Subject: [PATCH 28/38] enum for acl changed name from data to acl to match stack --- .../TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp index a145b0835ba..1e589acce4b 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack_adaptation/custom_chci_tr.cpp @@ -33,7 +33,7 @@ uint16_t CustomChciTrRead(uint8_t prot, uint8_t hci_type, uint16_t len, uint8_t controller_type = CHCI_TR_TYPE_CMD; break; case HCI_ACL_TYPE: - controller_type = CHCI_TR_TYPE_DATA; + controller_type = CHCI_TR_TYPE_ACL; break; case HCI_ISO_TYPE: controller_type = CHCI_TR_TYPE_ISO; @@ -56,7 +56,7 @@ uint16_t CustomChciTrWrite(uint8_t prot, uint8_t controller_type, uint16_t len, case CHCI_TR_TYPE_EVT: hci_type = HCI_EVT_TYPE; break; - case CHCI_TR_TYPE_DATA: + case CHCI_TR_TYPE_ACL: hci_type = HCI_ACL_TYPE; break; case CHCI_TR_TYPE_ISO: From 981eaed9bb0153e78d386c8b6fdf17c08ffaa9d3 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:23:33 +0100 Subject: [PATCH 29/38] crypto init calls fixed --- .../TARGET_NRF5x/stack/sources/pal_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c index 802215868fe..c484ab4d063 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_crypto.c @@ -30,7 +30,7 @@ #include "nrf_ecb.h" #include "nrf.h" -#if defined(NRF52840_XXAA) +#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION #include "nrf52840.h" /* Crypto Cell definitions */ #include "crys_rsa_kg.h" @@ -834,7 +834,7 @@ bool_t PalCryptoAesCcmDecrypt(PalCryptoEnc_t *pEnc, uint8_t *pBuf) return TRUE; } -#if defined(NRF52840_XXAA) +#if defined(NRF52840_XXAA) && defined(FEATURE_CRYPTOCELL310) && MBED_CONF_CORDIO_LL_NRF52840_CRYPTOCELL310_ACCELERATION /*************************************************************************************************/ /*! * \brief Execute the CCM-Mode encryption algorithm. From 3316e7ff66109db35f0bae8b8e911b83ea95cf44 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:24:25 +0100 Subject: [PATCH 30/38] shutdown timer on deinit --- .../TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c index eeb7befa0ef..cf4ceeaf219 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/stack/sources/pal_timer.c @@ -235,6 +235,7 @@ void PalTimerDeInit(void) /* stop timer */ NRF_TIMER2->TASKS_STOP = 1; + NRF_TIMER2->TASKS_SHUTDOWN = 1; #endif #endif From 666f2f4b79058ced570b75d81a4ee0c59d6d8d83 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 12 Jun 2020 08:25:05 +0100 Subject: [PATCH 31/38] trigger complete callbacks after sending HCI message --- .../stack/controller/sources/common/chci/chci_tr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c index e3c3c3de211..27152d6f843 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/sources/common/chci/chci_tr.c @@ -431,6 +431,7 @@ static void chciTrWrite(uint8_t prot, uint8_t type, uint16_t len, uint8_t *pData #if (CHCI_TR_CUSTOM == 1) CustomChciTrWrite(prot, type, len, pData); + chciTrSendComplete(); #endif } From bc44299512649782d7c5c826aca02a9fa7cf840a Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 15 Jun 2020 20:11:45 +0100 Subject: [PATCH 32/38] added timerboundary to config --- .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index 9db5da1e274..b12944ce021 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -92,9 +92,19 @@ using namespace ble::vendor::cordio; // The BB_ config macros are set in the bb_api.h header file const BbRtCfg_t NRFCordioHCIDriver::_bb_cfg = { /*clkPpm*/ 20, - /*rfSetupDelayUsec*/ BB_RF_SETUP_DELAY_US, - /*maxScanPeriodMsec*/ BB_MAX_SCAN_PERIOD_MS, - /*schSetupDelayUsec*/ BB_SCH_SETUP_DELAY_US + /*rfSetupDelayUs*/ BB_RF_SETUP_DELAY_US, + /*maxScanPeriodMs*/ BB_MAX_SCAN_PERIOD_MS, + /*schSetupDelayUs*/ BB_SCH_SETUP_DELAY_US, + /*BbTimerBoundaryUs*/ +#if (BB_CLK_RATE_HZ == 32768) + BB_RTC_MAX_VALUE_US +#elif (BB_CLK_RATE_HZ == 8000000) + BB_TIMER_8MHZ_MAX_VALUE_US +#elif (BB_CLK_RATE_HZ == 1000000) + BB_TIMER_1MHZ_MAX_VALUE_US +#else + #error "Unsupported platform." +#endif }; /* +12 for message headroom, + 2 event header, +255 maximum parameter length. */ From 3de3754a33ffd94a6a375d78eefb9fedef2db7a4 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 15 Jun 2020 20:12:06 +0100 Subject: [PATCH 33/38] switch to 5.1 api --- .../TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h index 0bf0a9c793a..aec6bae7178 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO_LL/stack/controller/include/ble/ll_init_api.h @@ -62,7 +62,7 @@ extern "C" { #ifndef BT_VER /*! \brief Initialize default BT version. */ -#define BT_VER LL_VER_BT_CORE_SPEC_5_2 +#define BT_VER LL_VER_BT_CORE_SPEC_5_1 #endif /************************************************************************************************** From 9354bc2a958966739adb0b9584c966bc13e675d5 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 15 Jun 2020 20:12:23 +0100 Subject: [PATCH 34/38] memory footprint increased --- .../TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index b12944ce021..439e007bbad 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -67,7 +67,7 @@ using namespace ble::vendor::cordio; #define MBED_CONF_CORDIO_LL_TX_BUFFERS MBED_CONF_CORDIO_LL_NRF52840_TX_BUFFERS #define MBED_CONF_CORDIO_LL_PHY_CODED_SUPPORT MBED_CONF_CORDIO_LL_NRF52840_PHY_CODED_SUPPORT -#define CORDIO_LL_MEMORY_FOOTPRINT 15400UL +#define CORDIO_LL_MEMORY_FOOTPRINT 16056UL #else From 2ffc61aacbd68897e8ab6f80db76a8a819f835ef Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Fri, 19 Jun 2020 16:35:11 +0100 Subject: [PATCH 35/38] added timer IRQ handler for TIMER2 --- .../TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index 439e007bbad..b0e52130bea 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -250,6 +250,8 @@ ble::vendor::cordio::buf_pool_desc_t NRFCordioHCIDriver::get_buffer_pool_descrip return buf_pool_desc_t(buffer, pool_desc); } +extern "C" void TIMER2_IRQHandler(); + void NRFCordioHCIDriver::do_initialize() { if(_is_init) { @@ -298,6 +300,7 @@ void NRFCordioHCIDriver::do_initialize() // For some reason, the mbed target uses this (TIMER0_IRQHandler_v) vector name instead of the "standard" TIMER0_IRQHandler one NVIC_SetVector(TIMER0_IRQn, (uint32_t)TIMER0_IRQHandler); + NVIC_SetVector(TIMER2_IRQn, (uint32_t)TIMER2_IRQHandler); // Extremely ugly for(uint32_t irqn = 0; irqn < 32; irqn++) From f2a6e8b0e8477c43108afbdc9c81294f7a5582b9 Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 22 Jun 2020 09:42:15 +0100 Subject: [PATCH 36/38] update comment --- .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index b0e52130bea..5ec877542d6 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -198,6 +198,7 @@ const LlRtCfg_t NRFCordioHCIDriver::_ll_cfg = { }; extern "C" void TIMER0_IRQHandler(void); +extern "C" void TIMER2_IRQHandler(void); NRFCordioHCIDriver::NRFCordioHCIDriver(CordioHCITransportDriver& transport_driver) : cordio::CordioHCIDriver(transport_driver), _is_init(false), _stack_buffer(NULL) { @@ -250,8 +251,6 @@ ble::vendor::cordio::buf_pool_desc_t NRFCordioHCIDriver::get_buffer_pool_descrip return buf_pool_desc_t(buffer, pool_desc); } -extern "C" void TIMER2_IRQHandler(); - void NRFCordioHCIDriver::do_initialize() { if(_is_init) { @@ -298,7 +297,8 @@ void NRFCordioHCIDriver::do_initialize() NRF_RADIO->POWER = 0; NRF_RADIO->POWER = 1; - // For some reason, the mbed target uses this (TIMER0_IRQHandler_v) vector name instead of the "standard" TIMER0_IRQHandler one + // mbed-os target uses IRQ Handler names with _v added at the end + // (TIMER0_IRQHandler_v and TIMER2_IRQHandler_v) so we need to register these manually NVIC_SetVector(TIMER0_IRQn, (uint32_t)TIMER0_IRQHandler); NVIC_SetVector(TIMER2_IRQn, (uint32_t)TIMER2_IRQHandler); From c3a39e9b4da1415e348af05fd504311b3e2ecc9a Mon Sep 17 00:00:00 2001 From: Paul Szczeanek Date: Mon, 22 Jun 2020 09:42:53 +0100 Subject: [PATCH 37/38] stray tabs removed --- .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index 5ec877542d6..ca3c9caad1e 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -305,10 +305,10 @@ void NRFCordioHCIDriver::do_initialize() // Extremely ugly for(uint32_t irqn = 0; irqn < 32; irqn++) { - uint8_t prio = NVIC_GetPriority((IRQn_Type)irqn); - if( prio < 2 ) { - NVIC_SetPriority((IRQn_Type)irqn, 2); - } + uint8_t prio = NVIC_GetPriority((IRQn_Type)irqn); + if( prio < 2 ) { + NVIC_SetPriority((IRQn_Type)irqn, 2); + } } // WARNING From 3e6e671d1771cbb753c05e021d68febe2804533d Mon Sep 17 00:00:00 2001 From: Paul Szczepanek Date: Fri, 3 Jul 2020 12:21:18 +0100 Subject: [PATCH 38/38] make public and random static based on different nrf configs --- .../TARGET_NRF5x/NRFCordioHCIDriver.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp index ca3c9caad1e..0aa92862693 100644 --- a/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_NORDIC/TARGET_NORDIC_CORDIO/TARGET_NRF5x/NRFCordioHCIDriver.cpp @@ -324,7 +324,15 @@ void NRFCordioHCIDriver::do_initialize() // BD Addr bdAddr_t bd_addr; - PalCfgLoadData(PAL_CFG_ID_BD_ADDR, bd_addr, sizeof(bdAddr_t)); + + /* Load address from nRF configuration. */ + uint64_t address_int = (((uint64_t)NRF_FICR->DEVICEADDR[0]) << 0) | + (((uint64_t)NRF_FICR->DEVICEADDR[1]) << 32); + unsigned int i = 0; + while (i++ < BDA_ADDR_LEN) { + bd_addr[i] = address_int >> (i * 8); + } + LlSetBdAddr((uint8_t *)&bd_addr); LlMathSetSeed((uint32_t *)&bd_addr);