diff options
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll')
31 files changed, 4611 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib Binary files differnew file mode 100644 index 0000000..e0e9915 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib Binary files differnew file mode 100644 index 0000000..aedb24e --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib Binary files differnew file mode 100644 index 0000000..63503ab --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib Binary files differnew file mode 100644 index 0000000..25cb7d3 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib Binary files differnew file mode 100644 index 0000000..afd9a9b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib Binary files differnew file mode 100644 index 0000000..12596fc --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt new file mode 100644 index 0000000..957d928 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2018, 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. + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h new file mode 100644 index 0000000..801cc3f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2008 - 2018, 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 __GZP_CONFIG_H +#define __GZP_CONFIG_H + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Definition of "secret key" used during "Host ID exchange". + */ + +#define GZP_SECRET_KEY {1, 23, 45, 57, 26, 68, 12, 64, 13, 73, 13, 62, 26, 45, 12, 77} + +//----------------------------------------------------------------------------- + +/** + Definition of the first static selected pairing channel. Should be located in + the lower Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_LOW 2 + +/** + Definition of the second static selected pairing channel. Should be located in + the upper Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_HIGH 79 + +/** + Definition of the static "global" pairing address. +*/ +#define GZP_ADDRESS 4, 6, 8, 10 + +/** + Reduced TX power for use during close proximity pairing. + */ +#define GZP_POWER NRF_GZLL_TX_POWER_N16_DBM + +/** + Definition of pairing request timeout. +*/ +#define GZP_REQ_TX_TIMEOUT 200 + +/** + Definition of the maximimum number of "backoff" packets (step 0) to be transmitted. +*/ +#define GZP_MAX_BACKOFF_PACKETS 100 + +/** + Definition of the period a device shall wait before attempting to send the packet for + fetching the pairing response (step 1). +*/ +#define GZP_TX_ACK_WAIT_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + 50) + +/** + Definition of the period a device in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT ((GZP_REQ_TX_TIMEOUT / 2) + 50) + +/** + Definition of the period a device NOT in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + GZP_STEP1_RX_TIMEOUT) + +/** + Definition of the time the host waits for a device to complete + transmission of the pairing request step 1 packet. +*/ +#define GZP_STEP1_RX_TIMEOUT (((GZP_REQ_TX_TIMEOUT / 2) + GZP_TX_ACK_WAIT_TIMEOUT) + 50) + +/** + Definition of the lowest boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MIN 2 + +/** + Definition of the upper boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MAX 80 + +/** + Definition of the minimum channel spacing for the channel subset generated + during pairing. +*/ +#define GZP_CHANNEL_SPACING_MIN 5 + +/** + Non volatile memory (Flash or OTP) storage address. A device will + require GZP_DEVICE_PARAMS_STORAGE_SIZE bytes of memory, and + Host 11 bytes. When using flash memory, storage address should + be a multiple of chip page size. +*/ +#define GZP_PARAMS_STORAGE_ADR 0x00001000 + +/** + Number of bytes available for parameter storage in Device. + It is equal to flash page size on nRF5x chips. +*/ +#if defined (NRF51) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 1024 +#elif defined (NRF52_SERIES) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 4096 +#else + #error Chip type is undefined! +#endif + +/** + Maximum Device TX payload length [bytes]. + */ +#define GZP_MAX_FW_PAYLOAD_LENGTH 17 + +/** + Maximum Host ACK payload length [bytes]. + */ +#define GZP_MAX_ACK_PAYLOAD_LENGTH 10 + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a Binary files differnew file mode 100644 index 0000000..8c9fe0a --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a Binary files differnew file mode 100644 index 0000000..4896b0c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a Binary files differnew file mode 100644 index 0000000..911ae7d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a Binary files differnew file mode 100644 index 0000000..46284ef --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a Binary files differnew file mode 100644 index 0000000..d463ca4 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a Binary files differnew file mode 100644 index 0000000..052634c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt new file mode 100644 index 0000000..957d928 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2018, 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. + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a Binary files differnew file mode 100644 index 0000000..bf4ad39 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a Binary files differnew file mode 100644 index 0000000..23fcdd1 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a Binary files differnew file mode 100644 index 0000000..755dbfd --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a Binary files differnew file mode 100644 index 0000000..b7971e6 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a Binary files differnew file mode 100644 index 0000000..36e7653 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a Binary files differnew file mode 100644 index 0000000..d09ca0f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt new file mode 100644 index 0000000..957d928 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2018, 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. + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h new file mode 100644 index 0000000..79a9ee8 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h @@ -0,0 +1,937 @@ +/** + * Copyright (c) 2012 - 2018, 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. + * + */ +/** + * @file + * @brief Gazell Link Layer API. + */ + +#ifndef NRF_GZLL_H__ +#define NRF_GZLL_H__ + +#include <stdbool.h> +#include "nrf.h" +#include "nrf_gzll_constants.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** +* @defgroup gzll_02_api Gazell Link Layer +* @{ +* @ingroup modules_01_gzll +* @brief Gazell Link Layer Application Programming Interface (API). +*/ + +/** + * @enum nrf_gzll_mode_t + * @brief Enumerator used for selecting Gazell mode. + */ +typedef enum +{ + NRF_GZLL_MODE_DEVICE, ///< Device mode + NRF_GZLL_MODE_HOST, ///< Host mode + NRF_GZLL_MODE_SUSPEND, ///< Suspend mode ("disabled with timer running") +} nrf_gzll_mode_t; + +/** + * @enum nrf_gzll_device_channel_selection_policy_t + * @brief Enumerator used for selecting Gazell Device channel + * selection policy. + */ +typedef enum +{ + NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL, ///< Start on previous successful channel + NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT, ///< Start on channel currently monitored by Host +} nrf_gzll_device_channel_selection_policy_t; + +/** + * @enum nrf_gzll_tx_power_t + * @brief Enumerator used for selecting the transmit (TX) power. + */ +typedef enum +{ + NRF_GZLL_TX_POWER_4_DBM, ///< 4 dBm transmit power. + NRF_GZLL_TX_POWER_0_DBM, ///< 0 dBm transmit power. + NRF_GZLL_TX_POWER_N4_DBM, ///< -4 dBm transmit power. + NRF_GZLL_TX_POWER_N8_DBM, ///< -8 dBm transmit power. + NRF_GZLL_TX_POWER_N12_DBM, ///< -12 dBm transmit power. + NRF_GZLL_TX_POWER_N16_DBM, ///< -16 dBm transmit power. + NRF_GZLL_TX_POWER_N20_DBM ///< -20 dBm transmit power. +} nrf_gzll_tx_power_t; + +/** + * @enum nrf_gzll_datarate_t + * @brief Enumerator used for selecting the radio datarate. + */ +typedef enum +{ +#ifdef NRF51 + NRF_GZLL_DATARATE_250KBIT = 0, ///< 250 Kbps datarate, available only for the nRF51. +#endif + NRF_GZLL_DATARATE_1MBIT = 1, ///< 1 Mbps datarate. + NRF_GZLL_DATARATE_2MBIT = 2 ///< 2 Mbps datarate. +} nrf_gzll_datarate_t; + +/** + * @enum nrf_gzll_xosc_ctl_t + * @brief Enumerator used for specifying whether switching the + * external 16 MHz oscillator on/off shall be handled automatically + * inside Gazell or manually by the application. + */ +typedef enum +{ + NRF_GZLL_XOSC_CTL_AUTO, ///< Switch XOSC on/off automatically + NRF_GZLL_XOSC_CTL_MANUAL ///< Switch XOSC on/off manually +} nrf_gzll_xosc_ctl_t; + +/** + * @enum nrf_gzll_error_code_t + * @brief Enumerator used for error codes for Gazell API functions + */ +typedef enum +{ + NRF_GZLL_ERROR_CODE_NO_ERROR = 0, ///< No error has been detected. + NRF_GZLL_ERROR_CODE_FAILED_TO_INITIALIZE = 1, ///< The function NRF_GZLL_init failed. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_CONFIGURE_WHEN_ENABLED = 2, ///< A call to a configuration 'set' function was made while Gazell was enabled. + NRF_GZLL_ERROR_CODE_POINTER_IS_NULL = 3, ///< A null pointer was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_PIPE = 4, ///< An invalid pipe number was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_MODE = 5, ///< An invalid value for the nrf_gzll_mode_t enumerator was given as input to a function. + NRF_GZLL_ERROR_CODE_INVALID_PAYLOAD_LENGTH = 6, ///< An invalid payload length was given as an input to a function. + NRF_GZLL_ERROR_CODE_INVALID_CHANNEL_TABLE_SIZE = 7, ///< An invalid channel table size was given as an input to a function. + NRF_GZLL_ERROR_CODE_INSUFFICIENT_PACKETS_AVAILABLE = 8, ///< There are insufficient packets in the Gazell memory pool to successfully execute the operation. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_ADD_TO_FULL_FIFO = 9, ///< There is insufficient space in the TX FIFO for the data packet. + NRF_GZLL_ERROR_CODE_NO_SPACE_IN_RX_FIFO_FOR_ACK = 10, ///< There is insufficient space in the RX FIFO for the ACK. + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FETCH_FROM_EMPTY_FIFO = 11, ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count() + NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FLUSH_WHEN_ENABLED = 12, ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count() + NRF_GZLL_ERROR_CODE_INVALID_PARAMETER = 14, ///< Attempted to set a variable which was not valid. + NRF_GZLL_ERROR_CODE_INTERNAL_ASSERT_OCCURRED = 15, ///< An internal assert occurred. + NRF_GZLL_ERROR_CODE_CALLBACK_NOT_IMPLEMENTED = 16, ///< A callback was called but not implemented by the application. + NRF_GZLL_ERROR_CODE_INVALID_ADDRESS = 17, ///< Invalid pipe 0 address detected, see Anomaly 107 at nRF52832 errata document. + NRF_GZLL_ERROR_CODE_NUMBER_OF_ERROR_CODES = 18, ///< Number of possible error codes. +} nrf_gzll_error_code_t; + +/** + * @struct nrf_gzll_device_tx_info_t; + * @brief Data structure containing information about the last packet + * transmission. + */ +typedef struct +{ + bool payload_received_in_ack; ///< A payload was received in the ACK. + uint16_t num_tx_attempts; ///< Number of attempts used on previous Device packet transmission. + uint16_t num_channel_switches; ///< Number of channel switches needed during previous packet transmission. + int8_t rssi; ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi(). + uint8_t rf_channel; ///< Channel on which packet has been transmitted. +} nrf_gzll_device_tx_info_t; + + +/** + * @struct nrf_gzll_host_rx_info_t; + * @brief Data structure containing information about the last packet + * received. + */ +typedef struct +{ + bool packet_removed_from_tx_fifo; ///< A payload was received in the ACK. + int8_t rssi; ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi(). + uint8_t rf_channel; ///< Channel on which packet has been received. +} nrf_gzll_host_rx_info_t; + + +typedef struct +{ + uint32_t packets_num; ///< Number of succesfully transmitted packets + uint32_t timeouts_num; ///< Total timeouts number + uint32_t channel_timeouts[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; ///< Transmission timeouts per channel + uint32_t channel_packets[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; ///< Succesfully transmitted packets per channel +} nrf_gzll_tx_statistics_t; + + +/**< Transmission timeout callback function definition */ +typedef void (*nrf_gzll_tx_timeout_callback)(uint32_t pipe, uint8_t rf_channel); + + +/**< Transmission CRC failure callback function definition */ +typedef void (*nrf_gzll_crc_failure_callback)(uint32_t pipe, uint8_t rf_channel); + + +#if defined(NRF52_SERIES) || defined(__SDK_DOXYGEN__) +/** + * @brief Data structure holding external front + * end control configuration. + */ +typedef struct +{ + bool pa_enabled; ///< Flag indicating if PA control is enabled. + bool pa_active_high; ///< Flag indicating if PA is active in high input state. + uint8_t pa_gpio_pin; ///< Number of output pin used for PA control. + uint8_t pa_gpiote_channel; ///< Number of GPIOTE channel used for PA control. + bool lna_enabled; ///< Flag indicating if LNA control is enabled. + bool lna_active_high; ///< Flag indicating if LNA is active in high input state. + uint8_t lna_gpio_pin; ///< Number of output pin used for LNA control. + uint8_t lna_gpiote_channel; ///< Number of GPIOTE channel used for LNA control. + NRF_TIMER_Type * timer; ///< Pointer to the TIMER instance. + uint8_t ppi_channels[NRF_GZLL_PA_LNA_PPI_CHANNELS_NUM]; ///< PPI channels used to control front end. + uint8_t ramp_up_time; ///< Determines how early should the PA/LNA be turned one before RADIO activity. Should be less than @ref NRF_GZLL_PA_LNA_MAX_RAMP_UP_TIME. +} nrf_gzll_pa_lna_cfg_t; +#endif + +/******************************************************************************/ +/** @name General API functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Initialize Gazell. + * + * @param mode The mode to initialize Gazell in. + * + * @retval true if Gazell initialized. + * @retval false if Gazell failed to initialize. + */ +bool nrf_gzll_init(nrf_gzll_mode_t mode); + +/** + * @brief Enable Gazell. + * + * When enabled the behaviour described for the current Gazell Link Layer mode + * will apply. + * + * @retval false if nrf_gzll_init has not previously been called or invalid address + * has been set - see Anomaly 107 at nRF52832 errata document. + */ +bool nrf_gzll_enable(void); + +/** + * @brief Disable Gazell. + * + * When calling this function the Gazell Link Layer will begin disabling, + * and will be fully disabled when Gazell calls nrf_gzll_disabled(). + * If there are any pending notifications, or if any new notifications are + * being added to the internal notification queue while Gazell is disabling, + * these will be sent to the application before Gazell is fully disabled. + * + * After Gazell has been fully disabled, no more notifications will be sent to + * the application. + */ +void nrf_gzll_disable(void); + +/** Check whether Gazell is enabled or disabled. + * + * @retval true If Gazell is enabled. + * @retval false If Gazell is disabled. + */ +bool nrf_gzll_is_enabled(void); + +/** @} */ + +/******************************************************************************/ +/** @name Device mode callback functions + * @{ */ +/******************************************************************************/ + +/** + * @brief ACK received callback (Device mode only). + * + * This callback is made when the Device receives an ACK (acknowledgement) + * packet. + * @sa nrf_gzll_ack_payload_received. + * + * @param pipe is the pipe on which an ACK packet was received. + * @param tx_info struct used to indicate whether a payload was received in the + * ack, as well as the number of TX attempts and channel switches required. + */ +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); + +/** + * @brief Transmission failed callback (Device mode only). + * + * This callback is made when a packet does not receive an ACK after + * nrf_gzll_max_retries is reached. The packet is deleted by Gazell. + * + * @param pipe is the pipe on which the transmission failed. + * @param tx_info struct used to indicate whether a payload was received + * in the ack, as well as RSSI and the number of TX attempts and + * channel switches required. + */ +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); + +/** @} */ + +/******************************************************************************/ +/** @name Host mode callback functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Data packet received callback (Host mode only). + * + * This callback is made when a Host receives a data packet from a Device. + * + * @param pipe is the pipe on which the data packet was received. + * @param rx_info struct used to indicate whether a payload was removed from the + * pipe's TX FIFO, as well as RSSI. + */ +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info); + +/** @} */ + +/******************************************************************************/ +/** @name Callback functions for both Device and Host mode + * @{ */ +/******************************************************************************/ + +/** + * @brief Disabled callback. + * + * This is called after Gazell enters the disabled state. + * There is no further CPU use by Gazell, the radio is disabled and the timer is + * powered down. + */ +void nrf_gzll_disabled(void); + +/** + * @brief Mode changed callbackl. + * + * This function is called after the Gazell mode has been changed. + * This function can only be called when Gazell is enabled. + */ +void nrf_gzll_mode_changed(void); + +/** @} */ + +/******************************************************************************/ +/** @name Packet transmission and receiving functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Add a packet to the tail of the TX FIFO. + * + * In Device mode, the packet will be added. + * In Host mode, the payload will be piggybacked onto an ACK. + * + * @param pipe Pipe to which to add the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param p_payload Pointer to the payload. + * @param length Number of bytes of the payload to transmit + * (0 to NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH). + * + * @retval true if the packet was successfully added to the TX FIFO. + * @retval false if unsuccessful, check nrf_gzll_error_code_t for more information. + */ +bool nrf_gzll_add_packet_to_tx_fifo(uint32_t pipe, uint8_t * p_payload, uint32_t length); + +/** + * @brief Fetch a packet from the head of the RX FIFO. + * + * @param pipe Pipe from which to fetch the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param p_payload Pointer to copy the payload to. + * @param p_length Length must be at least as large as the the number of bytes + * in the received payload length. + * + * @retval true If the fetch was successful. + * @retval false If unsuccessful, check nrf_gzll_error_code_t for more information. + */ +bool nrf_gzll_fetch_packet_from_rx_fifo(uint32_t pipe, uint8_t * p_payload, uint32_t * p_length); + +/** + * @brief Get the number of packets in the TX FIFO on a specific pipe. + * + * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * + * @retval >=0 The number of packets in the TX FIFO for the pipe. + * @retval -1 If the pipe number is invalid. + */ +int32_t nrf_gzll_get_tx_fifo_packet_count(uint32_t pipe); + +/** + * @brief Get the number of packets in the RX FIFO on a specific pipe. + * + * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval >=0 The number of packets in the RX FIFO for the pipe. + * @retval -1 If the pipe number is invalid. + */ +int32_t nrf_gzll_get_rx_fifo_packet_count(uint32_t pipe); + +/** + * @brief Get the total number of packets residing in all TX and RX FIFOs. + * + * Can be used to check against NRF_GZLL_CONST_MAX_TOTAL_PACKETS to + * determine if there is free space in the memory pool for more packets. + * + * @return The number of packets residing in all TX and RX FIFOs. + */ +uint32_t nrf_gzll_get_total_allocated_packet_count(void); + +/** + * @brief Check if adding a packet to a pipe's TX FIFO should be successful. + * + * Checks if there is another space in the pipe's TX and RX FIFOs + * as well as enough overall space in the packet pool. + * + * @param pipe The pip for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * + * @retval true If there is another space. + * @retval false If there is not enough space, or the pipe is invalid. + */ +bool nrf_gzll_ok_to_add_packet_to_tx_fifo(uint32_t pipe); + +/** + * @brief Flush the RX FIFO for a specific pipe. + * + * Delete all the packets and free the memory of the TX FIFO for a + * specific pipe. + * + * Note that it is not allowed to flush a TX FIFO when + * Gazell is enabled. + * + * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval true if the pipe was flushed. + * @retval false if the pipe was not flushed. + */ +bool nrf_gzll_flush_tx_fifo(uint32_t pipe); + +/** + * @brief Flush the RX FIFO for a specific pipe. + * + * Delete all the packets and free the memory of the RX FIFO for a + * specific pipe. + * + * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @retval true if the pipe was flushed. + * @retval false if the pipe was not flushed. + */ +bool nrf_gzll_flush_rx_fifo(uint32_t pipe); + +/** + * @brief Function for enabling transmission statistics. + * + * @param p_statistics Pointer to the statistics structure. + * + * @return True if channel statistics has been enabled, false otherwise. + */ +bool nrf_gzll_tx_statistics_enable(nrf_gzll_tx_statistics_t * p_statistics); + +/** + * @brief Function for disabling transmission statistics. + */ +void nrf_gzll_tx_statistics_disable(void); + +/** + * @brief Function for obtaining number of transmission timeouts for specific channel. + * + * @param[in] channel_index Channel index in channel table. + * @param[out] p_timeouts Pointer for the result. + * + * @return True in case of success, false otherwise. + */ +bool nrf_gzll_get_channel_timeouts(uint8_t channel_index, uint32_t *p_timeouts); + +/** + * @brief Function for clearing transmission statistic structure. + */ +void nrf_gzll_reset_tx_statistics(void); + +/** @} */ + +/******************************************************************************/ +/** @name Configuration functions + * + * Configuration 'set' functions may only be called while Gazell is disabled. The + * new parameter comes into effect when Gazell is enabled again. + * + * Configuration 'get' functions may be called at any time. + * + * @{ */ +/******************************************************************************/ + +/** + * @brief Function for registering callback to be called on the transmission timeout. + */ +void nrf_gzll_tx_timeout_callback_register(nrf_gzll_tx_timeout_callback callback); + + +/** + * @brief Function for registering callback to be called on the packet CRC failure. + */ +void nrf_gzll_crc_failure_callback_register(nrf_gzll_crc_failure_callback callback); + + +/** + * @brief Set the mode. + * + * @param mode The mode to be used. + * See nrf_gzll_mode_t for a list of valid modes. + * + * It is allowed to change mode when Gazell is enabled. If the mode is + * being changed while Gazell is enabled, the mode will not change right away. + * In this case the callback function nrf_gzll_mode_changed() will be called + * after the mdoe has changed. + * + * @retval true If the parameter was set. + */ +bool nrf_gzll_set_mode(nrf_gzll_mode_t mode); + +/** + * @brief Get function counterpart to nrf_gzll_set_mode(). + * + * @return The current mode. + */ +nrf_gzll_mode_t nrf_gzll_get_mode(void); + +/** + * @brief Set the base address for pipe 0. + * + * The full on-air address for each pipe is composed of a multi-byte base address + * prepended to a prefix byte. + * + * For packets to be received correctly, the most significant byte of + * the base address should not be an alternating sequence of 0s and 1s i.e. + * it should not be 0x55 or 0xAA. + * + * @param base_address The 4 byte base address. All bytes are used. + * + * @note Due to the nRF52 Anomaly 107, pipe 0 address should not have + * both prefix and two LSB of base address set to 0. + * + * @retval true If the parameter was set. + * @return false If Gazell was enabled. + */ +bool nrf_gzll_set_base_address_0(uint32_t base_address); + +/** + * @brief Get function counterpart to nrf_gzll_set_base_address_0(). + * + * @return Base address 0. + */ +uint32_t nrf_gzll_get_base_address_0(void); + +/** + * @brief Set the base address for pipes 1-7. + * + * Pipes 1 through 7 share base_address_1. @sa nrf_gzll_set_base_address_0. + * + * @param base_address The 4 byte base address. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_base_address_1(uint32_t base_address); + +/** + * @brief Get function counterpart to nrf_gzll_set_base_address_1(). + * + * @return Base address 1. + */ +uint32_t nrf_gzll_get_base_address_1(void); + +/** + * @brief Set the address prefix byte for a specific pipe. + * + * Each pipe should have its own unique prefix byte. + * + * @param pipe The pipe that the address should apply to. + * This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param address_prefix_byte The address prefix byte. + * + * @note Due to the Anomaly 107, pipe 0 address should not have + * both prefix and two LSB of base address set to 0. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled, or if the pipe was invalid. + */ +bool nrf_gzll_set_address_prefix_byte(uint32_t pipe, uint8_t address_prefix_byte); + +/** + * @brief Get function counterpart to nrf_gzll_set_address_prefix_byte(). + * + * @param pipe The pipe for which to get the address. + * This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * @param p_out_address_prefix_byte The pointer in which to return the + * address prefix byte. + * + * @retval true If the parameter was returned. + * @retval false If Gazell was enabled, the pipe was invalid or + * out_address was a NULL pointer. + */ +bool nrf_gzll_get_address_prefix_byte(uint32_t pipe, uint8_t * p_out_address_prefix_byte); + +/** + * @brief Set which pipes shall listen for packets in Host mode. + * + * This value is a bitmap, and each bit corresponds to a given pipe number. + * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1 + * and so forth. + * The maximum number of pipes is defined by NRF_GZLL_CONST_PIPE_COUNT. + * + * @param pipes A bitmap specifying which pipes to monitor. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_rx_pipes_enabled(uint32_t pipes); + +/** + * @brief Get function counterpart to nrf_gzll_set_rx_pipes_enabled(). + * + * @return Bitmap holding the current enabled pipes. + */ +uint32_t nrf_gzll_get_rx_pipes_enabled(void); + +/** + * @brief Set the timeslot period. + * + * The length in microseconds of a Gazell link layer timeslot. + * + * The minimum value of the timeslot period is dependent of the + * radio data rate (@sa nrf_gzll_set_datarate()). + * + * - For NRF_GZLL_DATARATE_2MBIT the timeslot period must be >= 600 us. + * - For NRF_GZLL_DATARATE_1MBIT the timeslot period must be >= 900 us. + * - For NRF_GZLL_DATARATE_250KBIT the timeslot period must be >= 2700 us. + * + * @param period_us The timeslot period in microseconds. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslot_period(uint32_t period_us); + +/** + * @brief Get function counterpart to nrf_gzll_get_timeslot_period(). + * + * @return The current timeslot period. + */ +uint32_t nrf_gzll_get_timeslot_period(void); + +/** + * @brief Set the Device channel selection policy + * + * The policy determines the initial channel when starting a new packet. + * transmission. + * + * @param policy The channel selection policy. + * + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL specifies + * that a new packet transmission always shall use the previous + * successful channel from the channel table. If Gazell is "in sync", Gazell + * will wait until this channel is being monitored by the Host before starting + * the transmission. + * + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT specifies that + * Gazell shall transmit on the channel that is currently being monitored by the + * Host. This parameter is only used when Gazell is "in sync". When "out of" sync, + * Gazell will always start using the "previous successful" channel. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled or the policy was invalid. + */ +bool nrf_gzll_set_device_channel_selection_policy(nrf_gzll_device_channel_selection_policy_t policy); + +/** + * @brief Get function counterpart to nrf_gzll_set_device_channel_selection_policy(). + * + * @return the Device channel selection policy. + */ +nrf_gzll_device_channel_selection_policy_t nrf_gzll_get_device_channel_selection_policy(void); + +/** + * @brief Set the number of timeslots that Gazell shall + * reside on a single channel before switching to another channel. + * + * This parameter applies in Host mode and for a Device that is + * in the "in sync" state. + * + * Since the Device and Host can not be in perfect synchronization, a + * transmission should overlap to adjacent timeslots on the Host. + * Therefore this value should be at least 2. + * + * @sa nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync + * + * @param timeslots The number of timeslots to reside on + * each channel before channel switch. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslots_per_channel(uint32_t timeslots); + +/** + * @brief Get function counterpart to nrf_gzll_set_timeslots_per_channel(). + * + * @return The current number of timeslots. + */ +uint32_t nrf_gzll_get_timeslots_per_channel(void); + +/** + * @brief Set the number of timeslots that a Gazell shall + * reside on a single channel before switching to another channel when + * in the "out of sync" state. + * + * This value should be set so that the Device transmits on one channel + * while the Host goes through a full channel rotation, i.e., + * channel_table_size*timeslots_per_channel. + * This ensures that the channels on the Device and Host will coincide + * at some point. + * Further increasing the value has been observed to provide better performance + * in the presence of interferers. + * + * @param timeslots The number of timeslots to reside on + * each channel before channel switch. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(uint32_t timeslots); + +/** + * @brief Get function counterpart to + * nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(). + * + * @return The current number of timeslots. + */ +uint32_t nrf_gzll_get_timeslots_per_channel_when_device_out_of_sync(void); + +/** + * @brief Set the number of timeslots after a successful + * reception of a Device or Host packet that the Gazell Link Layer shall assume + * that the link is synchronized. A value of 0 implies that the + * link is always out of sync. + * + * @param lifetime The sync lifetime in number of timeslots. + * + * @retval true If the sync lifetime was set. + * @retval false If Gazell was enabled. + */ +bool nrf_gzll_set_sync_lifetime(uint32_t lifetime); + +/** + * @brief Get function counterpart to nrf_gzll_set_sync_lifetime(). + * + * @return The sync lifetime measured in number of timeslots. + */ +uint32_t nrf_gzll_get_sync_lifetime(void); + +/** + * @brief Set the maximum number of TX attempts + * that can be used for a single packet. + * + * After the maximum number of attempts have been spent without + * receiving any ACK from the Host, the transmission will be terminated + * and the nrf_gzll_device_tx_failed() callback will be called. A zero + * value of the function parameter implies the infinite number of TX attempts. + * + * @param max_tx_attempts The maximum number of TX attempts. + */ +void nrf_gzll_set_max_tx_attempts(uint16_t max_tx_attempts); + +/** + * @brief Get function counterpart to nrf_gzll_set_max_tx_attempts(). + * + * @return The current max Device TX attempts. + */ +uint16_t nrf_gzll_get_max_tx_attempts(void); + +/** + * @brief Set the table of Radio Frequency (RF) channels. + * + * The valid channels are in the range 0 <= channel <= 125, where the + * actual centre frequency is (2400 + channel) MHz. + * The maximum channel table size is defined by + * NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE. + * + * @param p_channel_table Pointer to the channel table. + * @param size The size of the channel table. + * + * @retval true If the channel table was set. + * @retval false If Gazell was enabled, or the channel_table pointer was NULL, + * or the size was invalid. + */ +bool nrf_gzll_set_channel_table(uint8_t * p_channel_table, uint32_t size); + +/** + * @brief Get the table of Radio Frequency (RF) channels. + * + * @param p_channel_table Pointer to copy the channel table to. + * @param p_size Pointer to copy the size of the channel table to. + * The value already at size must be at least the size + * of the channel table. + * + * @retval true If the channel table was copied to channel_table. + * @retval false If the channel_table pointer was NULL, + * or the size was not large enough. + */ +bool nrf_gzll_get_channel_table(uint8_t * p_channel_table, uint32_t * p_size); + +/** + * @brief Get the current channel table size. + * + * @return The current channel table size. + */ +uint32_t nrf_gzll_get_channel_table_size(void); + +/** + * @brief Set the radio TX power. + * + * @param tx_power TX power. + * + * @retval true If the parameter was set. + * @retval false If the TX power was invalid. +*/ +bool nrf_gzll_set_tx_power(nrf_gzll_tx_power_t tx_power); + +/** + * @brief Get function counterpart to nrf_gzll_set_tx_power(). + * + * @return The current TX power. + */ +nrf_gzll_tx_power_t nrf_gzll_get_tx_power(void); + +/** + * @brief Set the radio datarate. + * + * @param data_rate Datarate. + * + * @retval true If the parameter was set. + * @retval false If Gazell was enabled or the datarate was invalid. + */ +bool nrf_gzll_set_datarate(nrf_gzll_datarate_t data_rate); + +/** + * @brief Get function counterpart to nrf_gzll_set_datarate(). + * + * @return The current datarate. + */ +nrf_gzll_datarate_t nrf_gzll_get_datarate(void); + +/** + * @brief Set whether start/stop of external oscillator (XOSC) shall be handled + * automatically inside Gazell or manually by the application. + * + * When controlling the XOSC manually from the application it is + * required that the XOSC is started before Gazell is enabled. + * + * When start/stop of the XOSC is handled automatically by Gazell, + * the XOSC will only be running when needed, that is when the radio + * is being used or when Gazell needs to maintain synchronization. + * + * It is required that the XOSC is started in order for the radio to be + * able to send or receive any packets. + * + * @param xosc_ctl setting for XOSC control. + * + * @retval true if the parameter was set. + * @retval false if Gazell was enabled or the xosc_ctl value was invalid. + */ +bool nrf_gzll_set_xosc_ctl(nrf_gzll_xosc_ctl_t xosc_ctl); + +/** + * Get function counterpart for nrf_gzll_set_xosc_ctl(); + * + * @return The XOSC control setting. + */ +nrf_gzll_xosc_ctl_t nrf_gzll_get_xosc_ctl(void); + +/** + * @brief Set Gazell to disable automatically after a certain number of timeslot ticks. + * + * @param num_ticks Number of timeslot ticks. + * + */ +void nrf_gzll_set_auto_disable(uint32_t num_ticks); + +#if defined(NRF52_SERIES) || defined(__SDK_DOXYGEN__) +/** + * @brief Set up external front end control. + * + * @param p_pa_lna_cfg Pointer to the configuration struct. + */ +bool nrf_gzll_set_pa_lna_cfg(nrf_gzll_pa_lna_cfg_t const * p_pa_lna_cfg); +#endif + +/** + * @brief Get the number of timeslot ticks that have occurred since + * nrf_gzll_init() was called. + * + * @return Number of timeslot ticks. + * + */ +uint32_t nrf_gzll_get_tick_count(void); + +/** + * @brief Clear the internal timeslot tick count variable that is read + * by nrf_gzll_get_tick_count(). + * + */ +void nrf_gzll_clear_tick_count(void); + +/** @} */ + +/******************************************************************************/ +/** @name Error handling functions + * @{ */ +/******************************************************************************/ + +/** + * @brief Gets the Gazell error code. + * + * @return The current error code. + */ +nrf_gzll_error_code_t nrf_gzll_get_error_code(void); + + +/** + * @brief Reset the Gazell error code. + * + * The error code is reset to NRF_GZLL_ERROR_CODE_NO_ERRROR. + */ +void nrf_gzll_reset_error_code(void); + +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h new file mode 100644 index 0000000..80df7c1 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2011 - 2018, 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. + * + */ +/** + * @file + * @brief Gazell Link Layer constants and default values. + * + * NOTE! Changing values here has no effect. They are only provided as a reference. + */ + +#ifndef NRF_GZLL_CONSTANTS_H__ +#define NRF_GZLL_CONSTANTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup gzll_02_api + * @{ + */ + + +/*****************************************************************************/ +/** @name Hardware resources used by Gazell */ +/*****************************************************************************/ +#define NRF_GZLL_HIGH_IRQ_PRIORITY 0 ///< Interrupt priority the Gazell timer and the radio +#define NRF_GZLL_LOW_IRQ_PRIORITY 1 ///< Interrupt priority for Gazell callback functions. + +#ifndef USE_SD_HW_RESOURCES + +#define NRF_GZLL_SWI_IRQn SWI0_IRQn ///< Software interrupt # used for callback functions. +#define NRF_GZLL_SWI_IRQ_HANDLER SWI0_IRQHandler ///< Software interrupt handler used for callback functions. +#define NRF_GZLL_TIMER NRF_TIMER2 ///< Timer to be used as flywheel timer. +#define NRF_GZLL_TIMER_IRQn TIMER2_IRQn ///< Interrupt # for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer. + +// In addition, Gazell uses the radio peripheral and radio interrupts. + +/* + * PPI configuration + */ +#define NRF_GZLL_PPI_EEP0 (NRF_PPI->CH0_EEP) ///< Gazell PPI event endpoint 0 +#define NRF_GZLL_PPI_TEP0 (NRF_PPI->CH0_TEP) ///< Gazell PPI task endpoint 0 +#define NRF_GZLL_PPI_EEP1 (NRF_PPI->CH1_EEP) ///< Gazell PPI event endpoint 1 +#define NRF_GZLL_PPI_TEP1 (NRF_PPI->CH1_TEP) ///< Gazell PPI task endpoint 1 +#define NRF_GZLL_PPI_EEP2 (NRF_PPI->CH2_EEP) ///< Gazell PPI event endpoint 2 +#define NRF_GZLL_PPI_TEP2 (NRF_PPI->CH2_TEP) ///< Gazell PPI task endpoint 2 + +#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x03) ///< Channel enable/disable mask for PPI endpoint 0 and 1. +#define NRF_GZLL_PPI_CHEN_MSK_2 (0x04) ///< Channel enable/disable mask for PPI endpoint 2. + +#else + +#define NRF_GZLL_SWI_IRQn SWI1_IRQn ///< Software interrupt # used for callback functions. +#define NRF_GZLL_SWI_IRQ_HANDLER SWI1_IRQHandler ///< Software interrupt handler used for callback functions. +#define NRF_GZLL_TIMER NRF_TIMER0 ///< Timer to be used as flywheel timer. +#define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER0_Msk ///< PERPOWER mask for the timer. +#define NRF_GZLL_TIMER_IRQn TIMER0_IRQn ///< Interrupt # for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer. + +// In addition, Gazell uses the radio peripheral and radio interrupts. + +/* + * PPI configuration + */ +#define NRF_GZLL_PPI_EEP0 (NRF_PPI->CH8_EEP) ///< Gazell PPI event endpoint 0 +#define NRF_GZLL_PPI_TEP0 (NRF_PPI->CH8_TEP) ///< Gazell PPI task endpoint 0 +#define NRF_GZLL_PPI_EEP1 (NRF_PPI->CH9_EEP) ///< Gazell PPI event endpoint 1 +#define NRF_GZLL_PPI_TEP1 (NRF_PPI->CH9_TEP) ///< Gazell PPI task endpoint 1 +#define NRF_GZLL_PPI_EEP2 (NRF_PPI->CH10_EEP) ///< Gazell PPI event endpoint 2 +#define NRF_GZLL_PPI_TEP2 (NRF_PPI->CH10_TEP) ///< Gazell PPI task endpoint 2 + +#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x300) ///< Channel enable/disable mask for PPI endpoint 0 and 1. +#define NRF_GZLL_PPI_CHEN_MSK_2 (0x400) ///< Channel enable/disable mask for PPI endpoint 2. + +#endif +/** @} */ + +/*****************************************************************************/ +/** @name Constant pipe and FIFO configuration */ +/*****************************************************************************/ +#define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). +#define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. +#define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. +#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. +#define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. +/** @} */ + +/*****************************************************************************/ +/** @name Default radio configuration */ +/*****************************************************************************/ +#define NRF_GZLL_DEFAULT_TX_POWER NRF_GZLL_TX_POWER_0_DBM ///< Default TX power. +#define NRF_GZLL_DEFAULT_DATARATE NRF_GZLL_DATARATE_2MBIT ///< Default data rate. + +#define NRF_GZLL_DEFAULT_CHANNEL_TABLE {4, 25, 42, 63, 77} ///< Default channel table. +#define NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE 5 ///< Default channel table size. +#define NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE 16 ///< Maximum channel table size allowed by Gazell. +/** @} */ + +/*****************************************************************************/ +/** @name Default Address configuration */ +/*****************************************************************************/ + +/* +Corresponds to Legacy nRFgo SDK Gazell config: +#define GZLL_DEFAULT_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} +#define GZLL_DEFAULT_ADDRESS_PIPE1 {0x02, 0x05, 0x08, 0x0B, 0x0E} +#define GZLL_DEFAULT_ADDRESS_PIPE2 3 +#define GZLL_DEFAULT_ADDRESS_PIPE3 4 +#define GZLL_DEFAULT_ADDRESS_PIPE4 5 +#define GZLL_DEFAULT_ADDRESS_PIPE5 6 +*/ + +#define NRF_GZLL_DEFAULT_FULL_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} ///< Corresponding legacy Gazell pipe 0 address. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_0 0x0D0A0704 ///< Default base address 0. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_1 0x0E0B0805 ///< Default base address 1. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_0 1 ///< Default prefix address pipe 0. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_1 2 ///< Default prefix address pipe 1. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_2 3 ///< Default prefix address pipe 2. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_3 4 ///< Default prefix address pipe 3. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_4 5 ///< Default prefix address pipe 4. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_5 6 ///< Default prefix address pipe 5. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_6 7 ///< Default prefix address pipe 6. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_7 8 ///< Default prefix address pipe 7. +#define NRF_GZLL_DEFAULT_BASE_ADDRESS_LENGTH NRF_GZLL_BASE_ADDRESS_LENGTH_4B ///< Default on-air base address length. +#define NRF_GZLL_DEFAULT_RX_PIPES_ENABLED 0x000000FF ///< Enabled Rx pipes. See nrf_gzll_set_rx_pipes_enabled(). +/** @} */ + +/*****************************************************************************/ +/** @name Default timeslot and synchronization configuration */ +/*****************************************************************************/ +#define NRF_GZLL_DEFAULT_TIMESLOT_PERIOD 600 ///< Default timeslot period. +#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL 2 ///< Timeslots use by the Host and by the Device when communication is in sync. +#define NRF_GZLL_DEFAULT_DEVICE_CHANNEL_SELECTION_POLICY NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL ///< Default channel Gazell Device channel selection policy +#define NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS 0 ///< Default maximum TX attempts for each packet. A value of zero implies the infinite number of TX attempts. +#define NRF_GZLL_DEFAULT_XOSC_CTL NRF_GZLL_XOSC_CTL_AUTO ///< Deafult setting for controlling the XOSC +#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL_WHEN_DEVICE_OUT_OF_SYNC 15 ///< Timeslots use by the Device before communication is in sync. +#define NRF_GZLL_DEFAULT_SYNC_LIFETIME (3 * NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE * NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL) ///< Number of timeslots to keep the timer running so that communication remains synchronized. +/** @} */ + +#define NRF_GZLL_PA_LNA_MAX_RAMP_UP_TIME 129 ///< Max external front end ramp up time [us]. +#define NRF_GZLL_PA_LNA_PPI_CHANNELS_NUM 4 ///< Number of PPI channels used for front end control. + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h new file mode 100644 index 0000000..6806a1b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2018, 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. + * + */ +/** + * @file + * @brief Gazell error API. + */ + +#ifndef NRF_GZLL_ERROR_H__ +#define NRF_GZLL_ERROR_H__ + +#include "sdk_errors.h" +#include "nrf_gzll.h" +#include "app_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GAZELLE_ERROR_CODE_CHECK(GZLL_RESULT) \ + do \ + { \ + if ((GZLL_RESULT) == false) \ + { \ + nrf_gzll_error_code_t gzll_error_code = nrf_gzll_get_error_code(); \ + ret_code_t error_code = gzll_error_code + NRF_ERROR_GAZELLE_ERR_BASE; \ + APP_ERROR_HANDLER(error_code); \ + } \ + } while (0) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h new file mode 100644 index 0000000..f419b6a --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2015 - 2018, 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 NRF_GZLL_RESOURCES_H__ +#define NRF_GZLL_RESOURCES_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GAZELL_ALTERNATIVE_RESOURCES + #define GZLL_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000004uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000001uL /**< Software interrupts used by Gazell */ +#else + #define GZLL_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000001uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000002uL /**< Software interrupts used by Gazell */ +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_GZLL_RESOURCES_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c new file mode 100644 index 0000000..07e0488 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c @@ -0,0 +1,363 @@ +/** + * Copyright (c) 2009 - 2018, 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Common functions. + * @defgroup gzp_source_common Gazell Pairing common functions implementation + * @{ + * @ingroup gzp_04_source + */ + + +#include "nrf_gzp.h" +#include "nrf_gzll.h" +#include "nrf_ecb.h" +#include <string.h> + + +#define SOURCE_FILE NRF_SOURCE_FILE_GZP ///< File identifer for asserts. + + +/******************************************************************************/ +/** @name Global variables + * @{ */ +/******************************************************************************/ + +/** + * Constant holding base address part of the pairing address. + */ +static const uint8_t pairing_base_address[4] = { GZP_ADDRESS }; + +/** + * Constant holding prefix byte of the pairing address. + */ +static const uint8_t pairing_address_prefix_byte = 0; + +/** + * Constant holding pre-defined "validation ID". + */ +static const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID; + +/** + * Constant holding pre-defined "secret key". + */ +static const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY; + +/** + * Variable used for AES key selection + */ +static gzp_key_select_t gzp_key_select; + + +/** @} */ + + +/******************************************************************************/ +/** @name Misc. external variables. + * @{ */ +/******************************************************************************/ +static uint8_t gzp_session_token[GZP_SESSION_TOKEN_LENGTH]; +static uint8_t gzp_dyn_key[GZP_DYN_KEY_LENGTH]; + +/** @} */ + +/******************************************************************************/ +/** @name Implementation common internal GZP functions + * @{ */ +/******************************************************************************/ +bool gzp_update_radio_params(const uint8_t* system_address) +{ + uint8_t i; + uint8_t channels[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; + uint32_t channel_table_size; + uint32_t pairing_base_address_32, system_address_32; + bool update_ok = true; + bool gzll_enabled_state; + + gzll_enabled_state = nrf_gzll_is_enabled(); + + // Configure "global" pairing address + pairing_base_address_32 = (pairing_base_address[0]) + + ((uint32_t)pairing_base_address[1] << 8) + + ((uint32_t)pairing_base_address[2] << 16) + + ((uint32_t)pairing_base_address[3] << 24) ; + if (system_address != NULL) + { + system_address_32 = (system_address[0]) + + ((uint32_t)system_address[1] << 8) + + ((uint32_t)system_address[2] << 16) + + ((uint32_t)system_address[3] << 24) ; + } + else + { + return false; + } + + nrf_gzp_disable_gzll(); + update_ok = update_ok && nrf_gzll_set_base_address_0(pairing_base_address_32); + update_ok = update_ok && nrf_gzll_set_address_prefix_byte(GZP_PAIRING_PIPE, pairing_address_prefix_byte); + update_ok = update_ok && nrf_gzll_set_base_address_1(system_address_32); + + // Configure address for pipe 1 - 5. Address byte set to equal pipe number. + for (i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + update_ok = update_ok && nrf_gzll_set_address_prefix_byte(i,i); + } + + channel_table_size = nrf_gzll_get_channel_table_size(); + gzp_generate_channels(&channels[0], system_address, channel_table_size); + + // Write generated channel subset to Gazell Link Layer + update_ok = update_ok && nrf_gzll_set_channel_table(&channels[0], channel_table_size); + if (gzll_enabled_state) + { + update_ok = update_ok && nrf_gzll_enable(); + } + return update_ok; +} + +void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8_t channel_tab_size) +{ + uint8_t binsize, spacing, i; + + binsize = (GZP_CHANNEL_MAX - GZP_CHANNEL_MIN) / channel_tab_size; + + ch_dst[0] = GZP_CHANNEL_LOW; + ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH; + + if (system_address != NULL) + { + for (i = 1; i < (channel_tab_size - 1); i++) + { + ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize); + } + } + + // If channels are too close, shift them to better positions + for (i = 1; i < channel_tab_size; i++) + { + spacing = (ch_dst[i] - ch_dst[i - 1]); + if (spacing < GZP_CHANNEL_SPACING_MIN) + { + ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing); + } + } +} + +__INLINE void nrf_gzp_disable_gzll(void) +{ + if (nrf_gzll_is_enabled()) + { + nrf_gzll_disable(); + __WFI(); + while (nrf_gzll_is_enabled()) + { + } + } +} + +#ifndef GZP_CRYPT_DISABLE + +void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length) +{ + uint8_t i; + + for (i = 0; i < length; i++) + { + *dst = *src ^ *pad; + dst++; + src++; + pad++; + } +} + +bool gzp_validate_id(const uint8_t* id) +{ + return (memcmp(id, (void*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH) == 0); +} + +void gzp_add_validation_id(uint8_t* dst) +{ + memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH); +} + +void gzp_crypt_set_session_token(const uint8_t * token) +{ + memcpy(gzp_session_token, (void const*)token, GZP_SESSION_TOKEN_LENGTH); +} + +void gzp_crypt_set_dyn_key(const uint8_t* key) +{ + memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH); +} + +void gzp_crypt_get_session_token(uint8_t * dst_token) +{ + memcpy(dst_token, (void const*)gzp_session_token, GZP_SESSION_TOKEN_LENGTH); +} + +void gzp_crypt_get_dyn_key(uint8_t* dst_key) +{ + memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); +} + +void gzp_crypt_select_key(gzp_key_select_t key_select) +{ + gzp_key_select = key_select; +} + +void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length) +{ + uint8_t i; + uint8_t key[16]; + uint8_t iv[16]; + + // Build AES key based on "gzp_key_select" + + switch (gzp_key_select) + { + case GZP_ID_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + break; + case GZP_KEY_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + gzp_get_host_id(key); + break; + case GZP_DATA_EXCHANGE: + memcpy(key, (void const*)gzp_secret_key, 16); + memcpy(key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); + break; + default: + return; + } + + // Build init vector from "gzp_session_token" + for (i = 0; i < 16; i++) + { + if (i < GZP_SESSION_TOKEN_LENGTH) + { + iv[i] = gzp_session_token[i]; + } + else + { + iv[i] = 0; + } + } + + // Set up hal_aes using new key and init vector + (void)nrf_ecb_init(); + nrf_ecb_set_key(key); + //hal_aes_setup(false, ECB, key, NULL); // Note, here we skip the IV as we use ECB mode + + // Encrypt IV using ECB mode + (void)nrf_ecb_crypt(iv, iv); + + // Encrypt data by XOR'ing with AES output + gzp_xor_cipher(dst, src, iv, length); + +} + +void gzp_random_numbers_generate(uint8_t * dst, uint8_t n) +{ + uint8_t i; + + NRF_RNG->EVENTS_VALRDY=0; + NRF_RNG->TASKS_START = 1; + for (i = 0; i < n; i++) + { + while (NRF_RNG->EVENTS_VALRDY==0) + {} + dst[i] = (uint8_t)NRF_RNG->VALUE; + NRF_RNG->EVENTS_VALRDY=0; + } + NRF_RNG->TASKS_STOP = 1; +} + + +/******************************************************************************/ +/** @name Implementation of nRF51 specific GZP functions + * @{ */ +/******************************************************************************/ + +/** +* @brief Function for setting the Primask variable. Only necessary if ARMCC +* compiler skips __set_PRIMASK at high optimization levels. +* +* @param primask The primask value. 1 to disable interrupts, 0 otherwise. +*/ +static void nrf_gzp_set_primask(uint32_t primask) +{ + #if defined(__CC_ARM) + //lint -save -e10 -e618 -e438 -e550 -e526 -e628 -e526 + volatile register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (primask); + #else + __set_PRIMASK(primask); + #endif + //lint -restore +} + +void nrf_gzp_flush_rx_fifo(uint32_t pipe) +{ + static uint8_t dummy_packet[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + uint32_t length; + + nrf_gzp_set_primask(1); + while (nrf_gzll_get_rx_fifo_packet_count(pipe) >0) + { + length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + (void)nrf_gzll_fetch_packet_from_rx_fifo(pipe,dummy_packet,&length); + } + nrf_gzp_set_primask(0); +} +/** @} */ + + + +/******************************************************************************/ +/** @name Implementation of debug functions + * @{ */ +/******************************************************************************/ + + +/** @} */ + +/** @} */ +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h new file mode 100644 index 0000000..336151f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h @@ -0,0 +1,665 @@ +/** + * Copyright (c) 2012 - 2018, 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. + * + */ +/** + * @file + * @brief Gazell Pairing API + */ + +#ifndef __GZP_H +#define __GZP_H + +#include "nrf.h" +#include "nrf_gzp_config.h" +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/** +* @defgroup gzp_02_api Gazell Pairing +* @{ +* @ingroup modules_02_gzp +* @brief Gazell Pairing Application Programming Interface (API). +*/ + + +/******************************************************************************/ +/** @name Pairing configuration defines + * @{ */ +/******************************************************************************/ + + +#define GZP_PAIRING_PIPE 0 ///< Pipe reserved for initial pairing communication. +#define GZP_DATA_PIPE 1 ///< Pipe reserved for GZP encrypted data communication (one pipe only). +#define GZP_TX_RX_TRANS_DELAY 10 ///< Time to wait between request and fetch packets in RX_PERIODS (2 timeslot periods) +#define GZP_SYSTEM_ADDRESS_WIDTH 4 ///< Must equal Gazell base address length. + + +#define GZP_VALIDATION_ID {0x32, 0x53, 0x66} ///< Validation ID. Required to be shared by Host and Device. Not a secret. +#define GZP_VALIDATION_ID_LENGTH 3 ///< Validation ID length in bytes. +#define GZP_HOST_ID_LENGTH 5 ///< Host ID length in bytes. +#define GZP_SESSION_TOKEN_LENGTH GZP_HOST_ID_LENGTH ///< Session token length in bytes. +#define GZP_DYN_KEY_LENGTH (16 - GZP_VALIDATION_ID_LENGTH) ///< Dynamic key length in bytes. + +#define GZP_HOST_RX_POWER_THRESHOLD -64 ///< RSSI threshold for when signal strength in RX packet power is high enough. + +/** @} */ + + +/******************************************************************************/ +/** @name Device -> Host packet definitions + * @{ */ +/******************************************************************************/ + +#define GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH 1 ///< "Host address request" packet, payload length + +#define GZP_CMD_HOST_ADDRESS_FETCH_PAYLOAD_LENGTH 1 ///< "Host address fetch" packet, payload length + +#define GZP_CMD_HOST_ID_REQ_SESSION_TOKEN 1 ///< "Host ID request" packet, session token position +#define GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_REQ_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Host ID request" payload length + +#if (GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH > 17) +#error GZP_SESSION_TOKEN_LENGTH too long. +#endif + + +#define GZP_CMD_HOST_ID_FETCH_VALIDATION_ID 1 ///< "Host ID fetch" packet +#define GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" payload length + +#if (GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH > 17) +#error GZP_VALIDATION_ID_LENGTH set too long. +#endif + +#define GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH 1 ///< "Key update prepare" payload length + +#define GZP_CMD_KEY_UPDATE_VALIDATION_ID 1 ///< "Key update" packet, validation ID position +#define GZP_CMD_KEY_UPDATE_NEW_KEY (GZP_CMD_KEY_UPDATE_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Key update" packet, new key position +#define GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_NEW_KEY + GZP_DYN_KEY_LENGTH) ///< "Key update" packet, payload length + +#if (GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH > 17) +#error Sum (GZP_VALIDATION_ID_LENGTH + GZP_DYN_KEY_LENGTH) too high. +#endif + + +#define GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID 1 ///< "Encrypted user data" packet, validation ID position +#define GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD ((GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH)) ///< "Encrypted user data" packet, user data position +#define GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD ( GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" packet, packet overhead length +#define GZP_ENCRYPTED_USER_DATA_MAX_LENGTH (17 - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD) ///< "Encrypted user data" packet, max payload length + +#if (GZP_MAX_FW_PAYLOAD_LENGTH < 17) + #error GZP_MAX_FW_PAYLOAD_LENGTH must be greater or equal to 17. +#endif + +#define GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH 1 ///< General "fetch response" packet, payload_length + +/** @} */ + + +/******************************************************************************/ +/** @name Host -> Device packet definitions + * @{ */ +/******************************************************************************/ + + +#define GZP_CMD_HOST_ADDRESS_RESP_ADDRESS 1 ///< "Host address fetch" response packet, address position +#define GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ADDRESS_RESP_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< ///< "Host address fetch" response packet, payload length + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID 1 ///< "Host ID fetch" response packet, validation ID position +#define GZP_CMD_HOST_ID_FETCH_RESP_STATUS (GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" response packet, status position +#define GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID (GZP_CMD_HOST_ID_FETCH_RESP_STATUS + 1) ///< "Host ID fetch" response packet, Host ID position +#define GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID + GZP_HOST_ID_LENGTH) ///< "Host ID fetch" response packet, payload length + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN 1 ///< "Key update prepare" response packet, session token position +#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Key update prepare" response packet, payload length position + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH. +#endif + + +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN 1 ///< "Encrypted user data" response packet, session token position +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID (GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Encrypted user data" response packet, validation ID position +#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH (GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" response packet, payload length position + +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH) + #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH. +#endif + +#if (GZP_VALIDATION_ID_LENGTH > GZP_HOST_ID_LENGTH) + #error GZP_HOST_ID_LENGTH should be greater or equal to GZP_VALIDATION_ID_LENGTH. +#endif + +#if (GZP_SESSION_TOKEN_LENGTH != GZP_HOST_ID_LENGTH) + #error GZP_SESSION_TOKEN_LENGTH must equal GZP_HOST_ID_LENGTH. +#endif + +#ifdef GZLL_CRYPT_ENABLE + #error Gazell encryption can not be enabled when using the Gazell pairing library. \ + GZLL_CRYPT_ENABLE must be undefined. +#endif + +/** @} */ + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + + +/** + * @enum gzp_key_select_t + * @brief Enumerator used for selecting the key to be used for encryption. + */ +typedef enum +{ + GZP_ID_EXCHANGE, ///< "Secret key" only + GZP_KEY_EXCHANGE, ///< "Secret key" and "Host ID" + GZP_DATA_EXCHANGE ///< "Dynamic key" and "Host ID" +} gzp_key_select_t; + + +/** + * @enum gzp_cmd_t + * @brief Enumerator used in the first payload byte of each packet to + * indicate the packet type. + */ +typedef enum +{ + GZP_CMD_HOST_ADDRESS_REQ = 0, ///< Host address request + GZP_CMD_HOST_ADDRESS_FETCH, ///< Host address fetch + GZP_CMD_HOST_ID_REQ, ///< Host ID request + GZP_CMD_HOST_ID_FETCH, ///< Host ID fetch request + GZP_CMD_KEY_UPDATE_PREPARE, ///< Key update prepare + GZP_CMD_KEY_UPDATE, ///< Key update + GZP_CMD_ENCRYPTED_USER_DATA, ///< Encrypted user data + GZP_CMD_FETCH_RESP, ///< Fetch response + GZP_CMD_HOST_ADDRESS_RESP, ///< Host address response + GZP_CMD_HOST_ID_FETCH_RESP, ///< Host ID fetch response + GZP_CMD_KEY_UPDATE_PREPARE_RESP, ///< Key update prepare + GZP_CMD_ENCRYPTED_USER_DATA_RESP, ///< Encrypted user data response +} gzp_cmd_t; + + +/** + * @enum gzp_id_req_res_t + * @brief Enumerator used to identify the state of the current + * Host ID request. + */ +typedef enum +{ + GZP_ID_RESP_PENDING, ///< ID response pending + GZP_ID_RESP_GRANTED, ///< ID response granted + GZP_ID_RESP_REJECTED, ///< ID response rejected + GZP_ID_RESP_FAILED, ///< ID response failed + GZP_ID_RESP_NO_REQUEST ///< Default value. No ID request has yet been received. +} gzp_id_req_res_t; + + +/** @} */ + + +/******************************************************************************/ +/** @name Misc. function prototypes + * @{ */ +/******************************************************************************/ + +/** + * Set the session token. + * + * @param token Pointer to the session token to set. + */ +void gzp_crypt_set_session_token(const uint8_t *token); + + +/** + * Get the session token. + * + * @param dst_token Pointer to write the session token. + */ +void gzp_crypt_get_session_token(uint8_t *dst_token); + + +/** + * Set the dynamic key. + * + * @param dyn_key Pointer to the dynamic key to set. + */ +void gzp_crypt_set_dyn_key(const uint8_t* dyn_key); + + +/** + * Get the dynamic key. + * + * @param dst_key Pointer to write the dynamic key too. + */ +void gzp_crypt_get_dyn_key(uint8_t *dst_key); + + +/** + * Set the Host ID. + * + * @param src Pointer to the Host ID to set. + */ +static void gzp_set_host_id(const uint8_t* src); + + +/** + * Get the Host ID. + * + * @param dst Pointer to write the Host ID to. + */ +void gzp_get_host_id(uint8_t *dst); + + +/** + * Selecting what key-set that should be used when encrypting data + * using gzp_crypt(). + * + * @param key_select Key-set to use. + */ +void gzp_crypt_select_key(gzp_key_select_t key_select); + + +/** + * Encypt / decrypt data. + * + * The current "session token" will be used as initialization vector (IV). + * The AES key to be used is selected by gzp_crypt_select_key(). + * AES is a symmetric encryption scheme, this function can be used + * to perform both encryption and decryption. + * + * @param dst Destination to write encrypted data to. Should be 16 bytes long. + * @param src Source data to encrypt. + * @param length Length in bytes of src. + */ +void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length); + + +/** + * Compare the *src_id with a pre-defined validation ID. + * + * @param src_id Pointer to the source validation ID to compare to. + * + * @retval true If *src_id equals the pre-defined ID. + * @retval false If *src_id does not equal the pre-defined ID. + */ +bool gzp_validate_id(const uint8_t *src_id); + + +/** + * Add the pre-defined validation ID to dst_id. + * GZP_VALIDATION_ID_LENGTH bytes will be added. + * + * @param dst_id Pointer to add the GZP validation ID to. + */ +void gzp_add_validation_id(uint8_t *dst_id); + + +/** + * Generate random bytes. + * + * @param dst Destination to write the random bytes to. + * @param n Number of bytes to generate. + */ +void gzp_random_numbers_generate(uint8_t *dst, uint8_t n); + + +/** + * Update the channel table and the system address. + * + * The channel table is updated to pseudo-random set generated using the + * system address. The channel table still includes GZP_CHANNEL_MAX and + * GZP_CHANNEL_MIN. + * The system address is applied to base address 1 and therefore applies + * to pipes 1-7. + * + * @param system_address Pointer to the system_address to set. + * + * @retval true If theradio parameters were updated successfully. + * @retval false If there was an error updated the radio parameters. + */ +bool gzp_update_radio_params(const uint8_t *system_address); + + +/** + * Generate a set of channels from a 4 byte address. + * + * @param ch_dst Destination to write the channel set to. The channel set + * includes GZP_CHANNEL_MAX and GZP_CHANNEL_MIN. + * @param address Four byte address to generate the channel set from. + * @param channel_set_size Size of the channel set to generate. + */ +void gzp_generate_channels(uint8_t *ch_dst, const uint8_t * address, uint8_t channel_set_size); + + +/** + * Perform an XOR on two byte strings. + * + * @param dst Destination to write the result to. Should be of size length. + * @param src + * @param pad + * @param length Number of bytes to perform the XOR operation on. + */ +void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length); + + +/******************************************************************************/ +/** @name Common Device and Host functions + * @{ */ +/******************************************************************************/ + + +/** + * Initialization function. This function initializes the Gazell Pairing Library. + + * This function must be called before any of the other Gazell Pairing Library functions are + * used and must be called @b after gzll_init() is called. + * + */ +void gzp_init(void); + +/** + * Function for erasing all pairing data. + */ +void gzp_erase_pairing_data(void); + +/** + * Disable Gazell and sleep while waiting for nrf_gzll_disabled callback. + */ +void nrf_gzp_disable_gzll(void); + +/** + Function for cancelling an ongoing (pending) "Host ID request". + + After calling this function the "Host ID request" status will go to + "ID request Idle". +*/ +void gzp_id_req_cancel(void); + +/** + * Flush the GZLL RX FIFO for a specific pipe while GZLL is disabled. + * + * @param pipe Pipe. + */ +void nrf_gzp_flush_rx_fifo(uint32_t pipe); + +/** +@name Device functions +*/ + +/** + * Check whether current GZP packet transaction has completed. + * + * @retval true + * @retval false + */ +bool nrf_gzp_tx_complete(void); + +/** + * Check whether previous GZP packet transaction was successful. + * + * @retval true + * @retval false + */ +bool nrf_gzp_tx_success(void); + +/** + * Reset tx_complete status. + */ +void nrf_gzp_reset_tx_complete(void); + +/** + * Reset tx_success status. + */ +void nrf_gzp_reset_tx_success(void); + +/** +* Function to check whether a Device has existing pairing data, implying that it is +* paired to a Host. +* +* @retval -2 The pairing database is empty. +* @retval -1 The device has a system address but no Host ID. +* @retval >=0 The device has a system address and HostID at this index value in the database. +*/ +int8_t gzp_get_pairing_status(void); + +/** + Function for sending a "system address" request to a Host. + + When calling this function the Device will attempt acquiring the "system address" from + any Host within close proximity. + + If a host is located within close proximity and pairing is enabled in the Host, + a "system address" will be sent in return to the Device. + + The new "system address" will apply immediately in the Device, and the new "system address" + will be stored in non volatile (NV) memory. + + Note. Using OTP devices limits the number of times a new "system address" can + be stored in NV memory. + + @return + + @retval true if new "system address" was received from a Host. + @retval false if no "system address" was received from a Host. +*/ +bool gzp_address_req_send(void); + +/** + Function for sending a "Host ID request" to a Host. + + The "Host ID" is needed to be able to send encrypted data using + gzp_crypt_data_send(). + + The request will be sent using the "system address" previously received using + gzp_address_req_send(). + + It is not required that the Host is within close proximity in order to acquire the + "Host ID". + + The new "Host ID" will apply immediately for the Device, and the new "Host ID" + will be stored in non volatile (NV) memory. + + Note. Using OTP devices limits the number of times a new "Host ID" can + be stored in NV memory. + + @return + + @retval GZP_ID_RESP_PENDING if a "Host ID request" has been sent to the Host, but the Host application has + not yet decided whether to Grant or Reject the "ID request". + @retval GZP_ID_RESP_GRANTED if the "Host ID" has been received from the Host. The received "Host ID" will be stored + in non volatile memory. + @retval GZP_ID_RESP_REJECTED if the Host application has rejected the "Host ID request". + @retval GZP_ID_RESP_FAILED if failing to send a request or receive a response from the Host. +*/ +gzp_id_req_res_t gzp_id_req_send(void); + +/** + Function for sending encrypted user data to the Host. + + Before any data can be sent the Device must acquire both the Host's + "system address" by using gzp_address_req_send() and the "Host ID" by using + gzp_id_req_send(). + + @param *src is a pointer to the data packet to be sent. + @param length is the length of the data packet to be sent. + + + @return + @retval true if the data was successfully transmitted and decrypted by the Host. + @retval false if data transmission failed or Host failed to decryption data correctly. +*/ +bool gzp_crypt_data_send(const uint8_t *src, uint8_t length); + + +/** +@name Host functions +*/ + +/** + Function for enabling/disabling pairing in a host. When pairing is enabled the host will + be monitoring for "system address" and "Host ID" requests from Devices. + + A "system address request" received from a Device will always be granted. + When a "host ID request" has been received, the Host application have to grant, + reject or cancel this by using one of the following functions: + + - gzp_id_req_grant() + - gzp_id_req_reject() + - gzp_id_req_cancel() + + @param enable + @arg true enables pairing. + @arg false disables pairing. +*/ +void gzp_pairing_enable(bool enable); + +/** + * Execute the Gazell Pairing Library Host operation. + * + * This function must be called regularly by the Host application. + */ +void gzp_host_execute(void); + +/** + * Address exchanged check. + * + * @retval true If a "system address" was delivered to a requesting Device during the + * previous call to gzp_host_execute(); + * @retval false Otherwise. +*/ +bool gzp_address_exchanged(void); + +/** + Function for checking if a "Host ID request" has been received from a Device. + + If a request has been received, the Pairing library will enter "ID request pending" + state. + + The application is responsible for responding to this request by calling + one of the following functions: + + - gzp_id_req_grant() + - gzp_id_req_reject() + - gzp_id_req_cancel() + + @retval true if a "Host ID request" has been received (internal state is "ID request pending") + @retval false if no "Host ID request" has been received (internal state is "ID request idle") +*/ +bool gzp_id_req_received(void); + +/** + Function for rejecting the previously received "Host ID request". This function should be called + only when a "Host ID request" has been received (internal state is "ID request pending"). + + The internal state of the Pairing library will remain "ID request pending" until the a "reject" message + has been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". +*/ +void gzp_id_req_reject(void); + +/** + * Function for granting the previously received "Host ID request". This function should be called + only when a "Host ID request" has been received (internal state is "ID request pending"). + + The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has + been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". +*/ +void gzp_id_req_grant(void); + + +/** + * Check if user data has been received. + * + * @retval true If encrypted user data has been received. + * @retval false Otherwise. +*/ +bool gzp_crypt_user_data_received(void); + +/** + Function for reading encrypted user data. + + Note that the read user data will be automatically decrypted. Only data + that was decrypted correctly will be presented. + + @param dst* is a pointer to where the received data will be written. + @param length* is a pointer for returning the number of bytes received. Only 1 byte will + be writtem to length*. + + @return + @retval true if data has been received and is written to dst* + @retval false if no data has been received. +*/ +bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length); + + +/** + Function emulating behavior of gzll_rx_start() in legeacy nRF24xx Gaell + linbrary. + + This functions sets Gazell in Host mode and starts reception (enable). +*/ +void gzll_rx_start(void); + + +/** @} */ +/** @} */ +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c new file mode 100644 index 0000000..7ee4037 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c @@ -0,0 +1,1146 @@ +/** + * Copyright (c) 2009 - 2018, 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Device functions. + * @defgroup gzp_source_device Gazell Pairing Device implementation. + * @{ + * @ingroup gzp_04_source + */ + + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> + +#include "nrf_gzll.h" +#include "nrf_gzp.h" +#include "nrf_delay.h" +#include "nrf_nvmc.h" + +#define SOURCE_FILE NRF_SOURCE_FILE_GZP_DEVICE ///< File identifer for asserts. + +/******************************************************************************/ +/** @name Misc. defines + * @{ */ +/******************************************************************************/ + +#define GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS 0 ///< System address position. +#define GZP_PARAMS_DB_ELEMENT_HOST_ID (GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< Host ID position +#define GZP_PARAMS_DB_ELEMENT_SIZE (GZP_SYSTEM_ADDRESS_WIDTH + GZP_HOST_ID_LENGTH)///< Total size +#define GZP_PARAMS_DB_MAX_ENTRIES 14 ///< Maximum allowed entries in the database. + +/** @} */ + +/******************************************************************************/ +/** @name Derived parameters + * @{ */ +/******************************************************************************/ + +//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclare identifier" +#define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR ///< +#define GZP_PARAMS_DB_SIZE (GZP_PARAMS_DB_MAX_ENTRIES * GZP_PARAMS_DB_ELEMENT_SIZE) ///< + +#define GZP_INDEX_DB_ADR (GZP_PARAMS_STORAGE_ADR + GZP_PARAMS_DB_SIZE) ///< +#define GZP_INDEX_DB_SIZE (GZP_DEVICE_PARAMS_STORAGE_SIZE - GZP_PARAMS_DB_SIZE) ///< + +#if (GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE) + #error GZP_DEVICE_PARAMS_STORAGE_SIZE must be greater or equal to GZP_PAIRING_PARAMS_DB_SIZE +#elif (GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE ) + #warning GZP_DEVICE_PARAMS_STORAGE_SIZE to low to be able store any pairing parameters NV memory +#endif +/** @} */ + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + + +/** + * Possible return values for the function gzp_tx_rx_transaction() + */ +typedef enum +{ + GZP_TX_RX_SUCCESS, ///< ACK received. Transaction successful. + GZP_TX_RX_FAILED_TO_SEND, ///< + GZP_TX_RX_NO_RESPONSE ///< +} gzp_tx_rx_trans_result_t; +/** @} */ + + +/******************************************************************************/ +/** @name Internal variables + * @{ */ +/******************************************************************************/ + +static uint8_t gzp_system_address[GZP_SYSTEM_ADDRESS_WIDTH]; ///< +static uint8_t gzp_host_id[GZP_HOST_ID_LENGTH]; ///< +static uint8_t dyn_key[GZP_DYN_KEY_LENGTH]; +static bool gzp_id_req_pending = false; + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) function prototypes + * @{ */ +/******************************************************************************/ + +/** + * Function for sending an encrypted packet. + * + * The function waits for the transmission to complete. + * + * @param tx_packet Pointer to the packet to be sent. + * @param length Length of the packet to be sent. + * @param pipe Pipe on which the packet should be sent. + * + * @retval true If the transmission succeeded. + * @retval false If the transmission failed (timed out). + */ +static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe); + +/** + * Function sending the packet *tx_packet and a subsequent packet fetching the response + * to *tx_packet. + * + * @param tx_packet is a pointer to the packet to be sent. + * @param tx_length is the length of the packet to be sent. + * @param rx_dst is a pointer to where the received response packet should be stored. + * @param rx_length is a pointer to where the length of the received packet should be stored. + * @param pipe is the pipe on which the packet should be sent. + * + * @return result of the transaction. + */ + static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe); + +/** + * Function for sending an encrypted packet. The function detects whether the correct + * key was used, and attempts to send a "key update" to the host if the wrong key was being + * used. + + * @param tx_packet is a pointer to the packet to be sent. + * @param length is the length of the packet to be sent. + + * @retval true if transmission succeeded and packet was decrypted correctly by host. + * @retval false if transmission failed or packet was not decrypted correctly by host. + */ +static bool gzp_crypt_tx_transaction(const uint8_t *tx_packet, uint8_t length); + +/** + * Function updateing the "dynamic key" and sending a "key update" to the host. + * + * @retval true if key update succeeded. + * @retval false if if key update failed. + */ +static bool gzp_key_update(void); + +/** + * Function for adding an element to "parameters data base" in non volatile (NV) memory. An element is + * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID". + * + * The "parameters data base" can store up to GZP_DEVICE_PAIRING_PARAMS_DB_MAX_ENTRIES + * elements. + * + * @param src_element is a pointer to the element. + * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1) + * selecting the location in which the element will be stored. + */ +static void gzp_params_db_add(const uint8_t *src_element, uint8_t index); + +/** + * Function for reading an element from "parameters data base" in non volatile (NV) memory. An element is + * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID". + * + * @param dst_element is a pointer where the read element should be stored. + * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1). + * selecting the location that should be read. + */ +static void gzp_params_db_read(uint8_t* dst_element, uint8_t index); + +/** + * Function for writing an index to the "index data base" in non volatile (NV) memory. + * + * @param index is the index to be written to the data base. + */ +static void gzp_index_db_add(uint8_t index); + +/** + * Function for reading the index previously written to the "index data base" in NV memory. + * + * @return + */ +static uint8_t gzp_index_db_read(void); + +/** + * Check "index data base" is full. + * + * @retval true + * @retval false + */ +static bool gzp_index_db_full(void); + +/** + * Function returning @b true if the "index data base" is empty. + * + * @retval true + * @retval false + */ +static bool gzp_index_db_empty(void); + +/** + * Function returning @b true if array contains only 1s (0xff). + * + * @param *src is a pointer to the array to be evaluated. + * @param length is the length of the array to be evaluated. + * + * @retval true + * @retval false + */ +static bool gzp_array_is_set(const uint8_t* src, uint8_t length); + +/** + * Function for storing the current "system address" and "host ID" in NV memory. + * + * @param store_all selects whether only "system address" or both "system address" and + * "host ID" should be stored. + * @arg true selects that both should be stored. + * @arg false selects that only "system address" should be stored. + * + * @retval true + * @retval false + */ +static bool gzp_params_store(bool store_all); + +/** + * Restore the "system address" and "host ID" from NV memory. + * @retval true + * @retval false + */ +static bool gzp_params_restore(void); + +/** + * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us]. + * + * @param rx_periods + */ +void gzp_delay_rx_periods(uint32_t rx_periods); + +/** + * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us] using the + * gazell timer and not a delay loop. + * + * @param rx_periods + */ +void gzp_tick_sleep_rx_periods(uint32_t rx_periods); + +/* + * Print debug string. By default does nothing. + * + * If GZP_DEBUG is defined then the print string function is required to + * be implemented. + */ +void print_string(char* p_expr); + +/** @} */ + +/******************************************************************************/ +/** @name Internal (static) variables + * @{ */ +/******************************************************************************/ + +static nrf_gzll_device_tx_info_t latest_tx_info; ///< Information about the last TX attempt, e.g. RSSI of ACK. + +static volatile bool tx_complete; ///< Flag to indicate whether a GZLL TX attempt has completed. +static bool tx_success; ///< Flag to indicate whether a GZLL TX attempt was successful. + +// Define Macro to make array initialization nicer +#define REP4(X) X X X X + +#if defined(__ICCARM__) + #if GZP_PARAMS_DB_ADR == 0x1000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data" + #elif GZP_PARAMS_DB_ADR == 0x15000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data_sd" + #else + #error + #endif +#else +static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR))) +#endif += { + #define STATIC_INIT_VALUE 0xFFFFFFFF + #define STATIC_INIT_COUNT (GZP_DEVICE_PARAMS_STORAGE_SIZE / 4) + #define INIT_1 STATIC_INIT_VALUE, + #define INIT_4 REP4(INIT_1) + #define INIT_16 REP4(INIT_4) + #define INIT_64 REP4(INIT_16) + #define INIT_256 REP4(INIT_64) + #define INIT_1024 REP4(INIT_256) + + #if (STATIC_INIT_COUNT == 256) + INIT_256 + #elif (STATIC_INIT_COUNT == 1024) + INIT_1024 + #else + #error Gazell Pairing Library database not initialized properly! + #endif +}; ///< Database for storing keys. + + +/** @} */ + + +/******************************************************************************/ +// Implementation: Device-specific API functions +/******************************************************************************/ + + +void gzp_init() +{ + gzp_id_req_pending = false; + +#ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_restore(); +#endif + + // Update radio parameters from gzp_system_address + (void)gzp_update_radio_params(gzp_system_address); +} + + +void gzp_erase_pairing_data(void) +{ + // Erase database flash page so that it can be later written to. + nrf_nvmc_page_erase((uint32_t)database); +} + +bool gzp_address_req_send() +{ + //lint -save -e514 Unusual use of a Boolean expression (gzll_update_ok &= ...) + uint8_t i; + bool retval = false; + bool success; + uint8_t address_req[GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH]; + uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + nrf_gzll_tx_power_t temp_power; + uint32_t temp_max_tx_attempts; + bool gzll_update_ok = true; + + + // Store parameters that are temporarily changed + temp_max_tx_attempts = nrf_gzll_get_max_tx_attempts(); + temp_power = nrf_gzll_get_tx_power(); + + // Modify parameters + nrf_gzp_disable_gzll(); + nrf_gzll_set_max_tx_attempts(GZP_REQ_TX_TIMEOUT); + gzll_update_ok &= nrf_gzll_set_tx_power(GZP_POWER); + + // Flush RX FIFO + gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE); + gzll_update_ok &= nrf_gzll_enable(); + // Build "request" packet + address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_REQ; + + // Send a number of packets in order to broadcast that devices not within + // close proximity must back off. + for (i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++) + { + success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); + if (success) + { + nrf_gzp_flush_rx_fifo(GZP_PAIRING_PIPE); + } + else + { + break; + } + } + + gzp_delay_rx_periods(GZP_TX_ACK_WAIT_TIMEOUT); + // Send message for fetching pairing response from host. + address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH; + + success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); + if (success && latest_tx_info.payload_received_in_ack) + { + // If pairing response received + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + { + rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; //dummy placeholder + if (nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &rx_payload_length)) + { + if (rx_payload[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_RESP) + { + memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + gzll_update_ok &= gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]); + #ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_store(false); // "False" indicates that only "system address" part of DB element will be stored + #endif + retval = true; + } + } + } + } + else + { + gzp_delay_rx_periods(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT - GZP_TX_ACK_WAIT_TIMEOUT); + } + gzp_delay_rx_periods(GZP_STEP1_RX_TIMEOUT); + + // Clean-up and restore parameters temporarily modified + nrf_gzp_disable_gzll(); + gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE); + gzll_update_ok &= nrf_gzll_flush_tx_fifo(GZP_PAIRING_PIPE); + nrf_gzll_set_max_tx_attempts(temp_max_tx_attempts); + gzll_update_ok &= nrf_gzll_set_tx_power(temp_power); + gzll_update_ok &= nrf_gzll_enable(); + + if (!gzll_update_ok) + { + /* + The update of the Gazell parameters failed. Use nrf_gzll_get_error_code() + to investigate the cause. + */ + } + + return retval; + //lint -restore +} + +#ifndef GZP_CRYPT_DISABLE + +gzp_id_req_res_t gzp_id_req_send() +{ + uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH]; + uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + gzp_tx_rx_trans_result_t trans_result; + + // If no ID request is pending, send new "ID request" + if (!gzp_id_req_pending) + { + // Build "Host ID request packet" + tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_REQ; + + // Generate new session token + gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); + + // Send "Host ID request" + if (gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + { + // Update session token if "Host ID request" was successfully transmitted + gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); + gzp_id_req_pending = true; + + return GZP_ID_RESP_PENDING; + } + } + else // If "ID request is pending" send "fetch ID" packet + { + // Build "host ID fetch" packet + tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH; + gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]); + + // Encrypt "host ID fetch" packet + gzp_crypt_select_key(GZP_ID_EXCHANGE); + gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); + + trans_result = gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE); + // If packet was successfully sent AND a response packet was received + if (trans_result == GZP_TX_RX_SUCCESS) + { + // Validate response packet + if (rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP) + { + gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID])) + { + switch (rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]) + { + case GZP_ID_RESP_PENDING: + break; + case GZP_ID_RESP_REJECTED: + gzp_id_req_pending = false; + break; + case GZP_ID_RESP_GRANTED: + gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]); + gzp_random_numbers_generate(dyn_key, GZP_DYN_KEY_LENGTH); + gzp_crypt_set_dyn_key(dyn_key); + #ifndef GZP_NV_STORAGE_DISABLE + (void)gzp_params_store(true); + #endif + gzp_id_req_pending = false; + break; + default: + break; + } + + return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]; + } + else + { + gzp_id_req_pending = false; + return GZP_ID_RESP_REJECTED; + } + } + } + } + + gzp_id_req_pending = false; + return GZP_ID_RESP_FAILED; +} + +void gzp_id_req_cancel() +{ + gzp_id_req_pending = false; +} + +bool gzp_crypt_data_send(const uint8_t *src, uint8_t length) +{ + if (length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH) + { + if (gzp_crypt_tx_transaction(src, length)) + { + return true; + } + else + { + //print_string("GZP_CRYPT_TX failed\r\n"); + // Attempt key update if user data transmission failed + // during normal operation (!gzp_id_req_pending) + if (!gzp_id_req_pending) + { + //print_string("KEY UPDATE\r\n"); + if (gzp_key_update()) + { + return gzp_crypt_tx_transaction(src, length); + } + } + return false; + } + } + else + { + return false; + } +} + +#endif +/** @} */ + + +/******************************************************************************/ +// Implementation: Internal (static) functions +/******************************************************************************/ + +static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe) +{ + tx_complete = false; + tx_success = false; + + if (nrf_gzll_add_packet_to_tx_fifo(pipe,(uint8_t *)tx_packet, length)) + { + while (tx_complete == false) + { + __WFI(); + } + return tx_success; + } + else + { + return false; + } +} + +static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe) +{ + + gzp_tx_rx_trans_result_t retval; + uint8_t fetch_packet[GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH]; + bool tx_packet_success; + bool fetch_success; + uint32_t local_rx_length = GZP_MAX_ACK_PAYLOAD_LENGTH; + uint32_t temp_lifetime; + + nrf_gzp_flush_rx_fifo(pipe); + + retval = GZP_TX_RX_FAILED_TO_SEND; + + (void)nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} + temp_lifetime = nrf_gzll_get_sync_lifetime(); + (void)nrf_gzll_set_sync_lifetime(GZP_TX_RX_TRANS_DELAY * 3); // 3 = RXPERIOD * 2 + margin + (void)nrf_gzll_enable(); + + tx_packet_success = gzp_tx_packet(tx_packet, tx_length, pipe); + + if (tx_packet_success) + { + retval = GZP_TX_RX_NO_RESPONSE; + + nrf_gzp_flush_rx_fifo(pipe); + + fetch_packet[0] = (uint8_t)GZP_CMD_FETCH_RESP; + + gzp_tick_sleep_rx_periods(GZP_TX_RX_TRANS_DELAY); + + tx_packet_success = gzp_tx_packet(fetch_packet, GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe); + + if (tx_packet_success) + { + if (nrf_gzll_get_rx_fifo_packet_count(pipe)) + { + local_rx_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + fetch_success = nrf_gzll_fetch_packet_from_rx_fifo(pipe, rx_dst, &local_rx_length); + } + else + { + fetch_success = false; + } + + if (fetch_success) + { + retval = GZP_TX_RX_SUCCESS; + } + else + { + //print_string("GZP_TX_FETCH_FAILED\r\n"); + } + } + else + { + //print_string("GZP_TX_FETCH_NO_ACK\r\n"); + } + } + + (void)nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} + (void)nrf_gzll_set_sync_lifetime(temp_lifetime); + (void)nrf_gzll_enable(); + + return retval; +} + +#ifndef GZP_CRYPT_DISABLE + +static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length) +{ + uint8_t tx_packet[GZP_MAX_FW_PAYLOAD_LENGTH]; + uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + uint8_t tx_packet_length; + + gzp_tx_rx_trans_result_t result; + + tx_packet_length = length + (uint8_t)GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD; + + // Assemble tx packet + tx_packet[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA; + gzp_add_validation_id(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]); + memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length); + + // Encrypt tx packet + if (gzp_id_req_pending) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + } + else + { + gzp_crypt_select_key(GZP_DATA_EXCHANGE); + } + gzp_crypt(&tx_packet[1], &tx_packet[1], tx_packet_length - 1); + + // If packet was successfully sent AND a response packet was received + result = gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE); + if (result == GZP_TX_RX_SUCCESS) + { + if (rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP) + { + gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH); + + // Validate response in order to know whether packet was correctly decrypted by host + if (gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID])) + { + // Update session token if normal operation (!gzp_id_req_pending) + if (!gzp_id_req_pending) + { + gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + } + return true; + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: Validation ID bad\r\n"); + return false; + } + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: Bad CMD. \r\n"); + return false; + } + } + else + { + //print_string("GZP_CRYPT_TX_TRANS: gzp_tx_rx_trans not SUCCESS\r\n"); + return false; + } +} + +static bool gzp_key_update(void) +{ + uint8_t tx_packet[GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH], rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH]; + + // Send "prepare packet" to get session token to be used for key update + tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE; + + // If packet was successfully sent AND a response packet was received + if (gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS) + { + if (rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP) + { + gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + + // Build "key update" packet + tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE; + gzp_add_validation_id(&tx_packet[GZP_CMD_KEY_UPDATE_VALIDATION_ID]); + gzp_random_numbers_generate(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY], GZP_DYN_KEY_LENGTH); + gzp_crypt_set_dyn_key(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY]); + + // Encrypt "key update packet" + gzp_crypt_select_key(GZP_KEY_EXCHANGE); + gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); + + // Send "key update" packet + if (gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + { + return true; + } + } + } + + return false; +} + +#endif + +void gzp_set_host_id(const uint8_t * id) +{ + memcpy(gzp_host_id, id, GZP_HOST_ID_LENGTH); +} + +void gzp_get_host_id(uint8_t * dst_id) +{ + memcpy(dst_id, gzp_host_id, GZP_HOST_ID_LENGTH); +} + +static void gzp_params_db_add(const uint8_t* src_element, uint8_t index) +{ + nrf_nvmc_write_bytes((GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), src_element, (uint32_t)GZP_PARAMS_DB_ELEMENT_SIZE); +} + + +static void gzp_params_db_read(uint8_t* dst_element, uint8_t index) +{ + memcpy(dst_element,(uint8_t*)(GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), GZP_PARAMS_DB_ELEMENT_SIZE); +} + + +static void gzp_index_db_add(uint8_t val) +{ + int16_t i; + uint8_t temp_val; + uint32_t addr; + + // Search for unwritten loacation in index DB + for (i = 0; i < GZP_INDEX_DB_SIZE; i++) + { + temp_val = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + // Lower nibble + if (i != (GZP_INDEX_DB_SIZE - 1)) + { + if ((temp_val & 0x0f) == 0x0f) + { + temp_val = (temp_val & 0xf0) | val; + break; + } + // Upper nibble + else if ((temp_val & 0xf0) == 0xf0) + { + temp_val = (temp_val & 0x0f) | (val << 4); + break; + } + } + else + { + temp_val = (GZP_PARAMS_DB_MAX_ENTRIES << 4) | val; + break; + } + } + + // Write index DB + addr = (GZP_INDEX_DB_ADR + i); + nrf_nvmc_write_byte(addr, temp_val); +} + +static uint8_t gzp_index_db_read() +{ + uint8_t retval; + int16_t i; + + // Search for previously written location + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + { + retval = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + if (retval != 0xff) + { + break; + } + } + + if (retval == 0xff) + { + retval = GZP_PARAMS_DB_MAX_ENTRIES; // index db empty + } + else if ((retval & 0xf0) != 0xf0) + { + retval >>= 4; + } + else + { + retval &= 0x0f; + } + + return retval; +} + +int8_t gzp_get_pairing_status(void) +{ + uint8_t db_byte; + int8_t db_index; + int16_t i; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + uint8_t default_host_id[GZP_HOST_ID_LENGTH]; + + db_index = -2; + + // Populate default Host ID with F's. + for (i=0; i< GZP_HOST_ID_LENGTH; i++) + { + default_host_id[i] = 0xFF; + } + + // Search for previously written location + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + { + db_byte = *(uint8_t*)(GZP_INDEX_DB_ADR + i); + + // Check if idx has been written to + if (db_byte != 0xff) + { + // Convert 4-bit nibble to index + if ((db_byte & 0xf0) != 0xf0) + { + db_byte = (db_byte >> 4) & 0x0f; + } + else + { + db_byte = db_byte & 0x0f; + } + + // Retrieve database entry + gzp_params_db_read(temp_element, db_byte); + + // Check if database entry is all F's + if ( memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], default_host_id, GZP_HOST_ID_LENGTH) != 0) + { + + db_index = db_byte; + } + else + { + db_index = -1; + } + break; + } + } + + return db_index; +} + + +static bool gzp_index_db_full() +{ +#if (GZP_INDEX_DB_SIZE != 0) + return ((*(uint8_t*)(GZP_INDEX_DB_ADR + (GZP_INDEX_DB_SIZE - 1)) != 0xff)); +#else + return true; +#endif +} + +//lint -save -e506 Constant value boolean +static bool gzp_index_db_empty() +{ +#if (GZP_INDEX_DB_SIZE != 0) + return ((GZP_INDEX_DB_SIZE == 0) || ((*(uint8_t*)(GZP_INDEX_DB_ADR)) == 0xff)); +#else + return true; +#endif +} +//lint -restore + +static bool gzp_array_is_set(const uint8_t* src, uint8_t length) +{ + uint8_t i; + + for (i = 0; i < length; i++) + { + if (*(src++) != 0xff) + { + return false; + } + } + return true; +} + +static bool gzp_params_store(bool store_all) +{ + uint8_t i; + bool write_index_db = false; + bool write_param_db = false; + uint8_t new_db_index = 0; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + + // Search param DB to see if current setup exists + if (store_all) + { + // Search for: Current system address and host ID exists + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0)) + { + write_index_db = true; + new_db_index = i; + break; // System address + host_id allready exists in database + } + } + + // Search for: Current system address and cleared host ID + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \ + (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], GZP_HOST_ID_LENGTH))) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + new_db_index = i; + write_index_db = true; + write_param_db = true; + break; + } + } + } + + // Search for: Cleared system address and cleared host ID + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE)) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + new_db_index = i; + write_index_db = true; + write_param_db = true; + break; + } + } + } + } + else + { + // Search for: System address + any host ID + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) + { + //memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); + write_index_db = true; + new_db_index = i; + break; + } + } + + // Search for: System address cleared + if (!write_index_db) + { + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + { + gzp_params_db_read(temp_element, i); + + if (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH)) + { + memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); + write_index_db = true; + write_param_db = true; + new_db_index = i; + break; + } + } + } + } + + if (write_param_db) + { + gzp_params_db_add(temp_element, new_db_index); + } + + if (write_index_db) + { + if (!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES)) + { + gzp_index_db_add(new_db_index); + return true; + } + } + + return false; +} + +static bool gzp_params_restore(void) +{ + uint8_t i; + uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; + + if (!gzp_index_db_full() && !gzp_index_db_empty()) + { + i = gzp_index_db_read(); + + if (i < GZP_PARAMS_DB_MAX_ENTRIES) + { + gzp_params_db_read(temp_element, i); + memcpy(gzp_system_address, &temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + gzp_set_host_id(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID]); + return true; + } + } + + return false; +} + +void gzp_delay_rx_periods(uint32_t rx_periods) +{ + nrf_delay_us(rx_periods * 2 * nrf_gzll_get_timeslot_period()); +} + +void gzp_tick_sleep_rx_periods(uint32_t rx_periods) +{ + nrf_gzll_clear_tick_count(); + + while (nrf_gzll_get_tick_count() < 2 * rx_periods) + { + __WFI(); + } +} + + +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ + latest_tx_info = tx_info; + + tx_complete = true; + tx_success = true; +} + +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ + latest_tx_info = tx_info; + + tx_complete = true; + tx_success = false; +} + +bool nrf_gzp_tx_complete(void) +{ + return tx_complete; +} + +bool nrf_gzp_tx_success(void) +{ + return tx_success; +} + +void nrf_gzp_reset_tx_complete() +{ + tx_complete = false; +} + +void nrf_gzp_reset_tx_success() +{ + tx_success = false; +} + +void nrf_gzll_disabled(void) +{ +} + +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) +{ +} + +/** @} */ +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c new file mode 100644 index 0000000..6e331a9 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c @@ -0,0 +1,821 @@ +/** + * Copyright (c) 2009 - 2018, 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. + * + */ +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), Host functions. + * @defgroup gzp_source_host Gazell Pairing Host implementation + * @{ + * @ingroup gzp_04_source + */ + + +#include "nrf_gzp.h" +#include "nrf_gzll.h" +#include <string.h> +#include <stdint.h> +#include <stdbool.h> +#include "nrf_assert.h" +#include "nrf_ecb.h" +#include "nrf_nvmc.h" + + +//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclared identifier" +#define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR // Address of the GZP parameters flash page. + + +/******************************************************************************/ +/** @name Typedefs + * @{ */ +/******************************************************************************/ + +/** + * Definition of internal states. + */ +typedef enum +{ + GZP_ID_REQ_IDLE, ///< No Host ID request received from Device. + GZP_ID_REQ_PENDING, ///< Host ID request received and waiting on application to grant/reject. + GZP_ID_REQ_PENDING_AND_GRANTED, ///< Host ID request received and granted by application. + GZP_ID_REQ_PENDING_AND_REJECTED, ///< Host ID request received and rejected by application. +} gzp_id_req_stat_t; + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) function prototypes + * @{ */ +/******************************************************************************/ + + +/** + * Function for incrementing internal session counter. + */ +static void gzp_session_counter_inc(void); + + +/** + * Function for reading value of internal session counter. + * @param dst Current session counter. + */ +static void gzp_get_session_counter(uint8_t* dst); + + +/** + * Function processing received "system address request" from Device. + * + * @param gzp_req Pointer to RX payload containing system address request. + */ +static void gzp_process_address_req(uint8_t* gzp_req); + + +/** + * Function to process Host ID request from device. + * + * The Host shall retrieve the Host ID from NVM, or shall generate if + * it does not yet exist. + * + * @param rx_payload Pointer to rx_payload contaning Host ID request. + */ +static void gzp_process_id_req(uint8_t* rx_payload); + +/** + * Function to process Host ID fetch request from Device. + * + * The Device fetches the Host ID after the Host has generated/retrieved + * the Host ID. + * + * @param rx_payload Pointer to rx_payload contaning Host ID fetch request. + */ +static void gzp_process_id_fetch(uint8_t* rx_payload); + + +/** + * Function to process Key Update Prepare packet. + * + * Device requests the Session Token to be used for the Key Update request. + */ +static void gzp_process_key_update_prepare(void); + + +/** + * Function to process Key Update packet. + * + * Device requests a Key Update and sends a new Dynamic Key. The Dynamic Key is + * updated on the Host. + * + * @param rx_payload Pointer to rx_payload containing Key Update request. + */ +static void gzp_process_key_update(uint8_t* rx_payload); + + +/** + * Function to process received Encrypted User packet. + * + * @param rx_payload Pointer to rx_payload containing the encrypted user data. + * @param length Length of encrypted user data. + */ +static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length); + + +/** + * Function to preload the payload for the next ACK. + * + * @param src Pointer to source payload. + * @param length Length of source payload. + * @param pipe Pipe for the ACK payload. + */ +static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe); + + +/** + * Function for reading the Chip ID from non-volatile memory. + * + * The chip ID is used for the system address. + * + * If the Chip ID is not yet created a random Chip ID is created and + * written to non-volatile memory. Note that the term chip ID is used as + * the factory programmed chip sequence number was used for the system + * address in nRF24LU ICs. + * + * @param dst Address to copy Host ID to. + * @param[in] n Number of bytes in the Host ID. + */ +void gzp_host_chip_id_read(uint8_t *dst, uint8_t n); + + +/** + * Function to set the Host ID. + * + * Writes the Host ID to non-volatile memory. + * @param src Address of the Host ID to copy from. + */ +static void gzp_set_host_id(const uint8_t* src); + + +/** + * Function to request disabling of Gazell and wait for it to be disabled. + * + * Emulates legacy gzll_goto_idle(). + */ +static void gzll_goto_idle(void); + + +/** + * Flush all TX FIFOs. + * + * Emulates legacy gzll_tx_fifo_flush(). + */ +static void gzll_tx_fifo_flush(void); + + +/** + * Flush all RX FIFOs. + * + * Emulates legacy gzll_rx_fifo_flush(). + */ +static void gzll_rx_fifo_flush(void); + + +/** + * Set a timeout for the reception of packets on the Gazell Host. + * + * Emulates legacy Gazell function: gzll_set_param(GZLL_PARAM_RX_TIMEOUT, x). + * + * @param timeout Timeout in number of legacy "RX periods" + * (1 RX period = 2 timeslot periods). + */ +static void gzll_set_rx_timeout(uint32_t timeout); + +/** @} */ + + +/******************************************************************************/ +/** @name Internal (static) variabls + * @{ */ +/******************************************************************************/ + +static gzp_id_req_stat_t gzp_id_req_stat; ///< Current state of Host ID request. +static bool gzp_pairing_enabled_f; ///< True if Host is paired with a device. +static bool gzp_address_exchanged_f; ///< True if Host has exchanged a system address with a device and thus pairing has begun. + +static uint8_t gzp_session_counter[GZP_SESSION_TOKEN_LENGTH]; ///< Session counter used for key generation and update. + +static bool gzp_encrypted_user_data[GZP_ENCRYPTED_USER_DATA_MAX_LENGTH]; ///< Placeholder for encrypted data from Device. +static uint8_t gzp_encrypted_user_data_length; ///< Length of gzp_encrypted_user_data. Zero implies no data received. + +static nrf_gzll_host_rx_info_t prev_gzp_rx_info = {0, 0}; ///< RSSI and status of ACK payload transmission of previous Gazell packet. + +// Define Macro to make array initialization nicer +#define REP4(X) X X X X + +#if defined(__ICCARM__) + #if GZP_PARAMS_DB_ADR == 0x1000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data" + #elif GZP_PARAMS_DB_ADR == 0x15000 + static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data_sd" + #else + #error + #endif +#else +static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR))) +#endif += { + #define STATIC_INIT_VALUE 0xFFFFFFFF + #define STATIC_INIT_COUNT (GZP_DEVICE_PARAMS_STORAGE_SIZE / 4) + #define INIT_1 STATIC_INIT_VALUE, + #define INIT_4 REP4(INIT_1) + #define INIT_16 REP4(INIT_4) + #define INIT_64 REP4(INIT_16) + #define INIT_256 REP4(INIT_64) + #define INIT_1024 REP4(INIT_256) + + #if (STATIC_INIT_COUNT == 256) + INIT_256 + #elif (STATIC_INIT_COUNT == 1024) + INIT_1024 + #else + #error Gazell Pairing Library database not initialized properly! + #endif +}; ///< Database for storing keys. + +/** @} */ + + +/******************************************************************************/ +// Implementation: Host-specific API functions +/******************************************************************************/ + +void gzp_init() +{ + uint8_t system_address[GZP_SYSTEM_ADDRESS_WIDTH]; + + // Read "chip id", of which 4 bytes (GZP_SYSTEM_ADDRESS_WIDTH) + // are used as system address + gzp_host_chip_id_read(system_address, GZP_SYSTEM_ADDRESS_WIDTH); + + // Set up radio parameters (addresses and channel subset) from system_address + (void)gzp_update_radio_params(system_address); + + // Only "data pipe" enabled by default + + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_DATA_PIPE)); + + gzp_pairing_enabled_f = false; + gzp_address_exchanged_f = false; + gzp_id_req_stat = GZP_ID_REQ_IDLE; + gzp_encrypted_user_data_length = 0; + + // Infinite RX timeout + gzll_set_rx_timeout(0); +} + +void gzp_pairing_enable(bool enable) +{ + if (gzp_pairing_enabled_f != enable) + { + gzll_goto_idle(); + + if (enable) + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); + } + else + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() & ~(1 << GZP_PAIRING_PIPE)); + + gzp_id_req_stat = GZP_ID_REQ_IDLE; + } + + gzp_pairing_enabled_f = enable; + + gzll_rx_start(); + } +} + +void gzp_host_execute() +{ + bool gzp_packet_received = false; + uint32_t payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH]; + + gzp_address_exchanged_f = false; + + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + { + gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &payload_length); + } + + if (!gzp_packet_received && (gzp_encrypted_user_data_length == 0)) + { + if (nrf_gzll_get_rx_fifo_packet_count(GZP_DATA_PIPE) > 0) + { + gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_DATA_PIPE, rx_payload, &payload_length); + } + } + + if (gzp_packet_received) + { + //lint -save -esym(644,rx_payload) //may not have been initialized + switch (rx_payload[0]) + { + case GZP_CMD_HOST_ADDRESS_REQ: + gzp_process_address_req(rx_payload); + break; + + #ifndef GZP_CRYPT_DISABLE + + case GZP_CMD_HOST_ID_REQ: + gzp_process_id_req(rx_payload); + break; + case GZP_CMD_HOST_ID_FETCH: + gzp_process_id_fetch(rx_payload); + break; + case GZP_CMD_KEY_UPDATE_PREPARE: + gzp_process_key_update_prepare(); + break; + case GZP_CMD_KEY_UPDATE: + gzp_process_key_update(rx_payload); + break; + case GZP_CMD_ENCRYPTED_USER_DATA: + gzp_process_encrypted_user_data(rx_payload, payload_length); + break; + + #endif + + case GZP_CMD_FETCH_RESP: + default: + break; + } + } + + // Restart reception if "not proximity backoff" period has elapsed + if (!nrf_gzll_is_enabled()) + { + gzll_set_rx_timeout(0); + + if (gzp_pairing_enabled_f) + { + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); + } + + gzll_rx_start(); + } + + #ifndef GZP_CRYPT_DISABLE + gzp_session_counter_inc(); + #endif +} + +void gzll_rx_start(void) +{ + if (nrf_gzll_get_mode() != NRF_GZLL_MODE_HOST) + { + gzll_goto_idle(); + (void)nrf_gzll_set_mode(NRF_GZLL_MODE_HOST); + } + + if (!nrf_gzll_is_enabled()) + { + (void)nrf_gzll_enable(); + } +} + +bool gzp_id_req_received() +{ + return (gzp_id_req_stat != GZP_ID_REQ_IDLE); +} + +void gzp_id_req_reject() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_REJECTED; + } +} + +void gzp_id_req_grant() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_GRANTED; + } +} + +void gzp_id_req_cancel() +{ + if (gzp_id_req_received()) + { + gzp_id_req_stat = GZP_ID_REQ_IDLE; + } +} + +//----------------------------------------------------------------------------- +// Implementation: Static functions +//----------------------------------------------------------------------------- + +static void gzp_process_address_req(uint8_t* gzp_req) +{ + uint8_t temp_rx_pipes; + uint8_t pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH]; + uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; + + gzp_address_exchanged_f = false; + + gzll_goto_idle(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + temp_rx_pipes = nrf_gzll_get_rx_pipes_enabled(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + // If requesting Device within close proximity + if (prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD) + { + (void)nrf_gzll_set_rx_pipes_enabled(0); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + gzll_set_rx_timeout(GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + gzll_rx_fifo_flush(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + // Start "proximity" back off period + gzll_rx_start(); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + + while (nrf_gzll_is_enabled()) + {} + + // Build pairing response packet + pairing_resp[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_RESP; + gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); + + (void)nrf_gzll_add_packet_to_tx_fifo(0, &pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzll_set_rx_timeout(GZP_STEP1_RX_TIMEOUT); + + // Enable only pairing pipe when waiting for pairing request step 1 + (void)nrf_gzll_set_rx_pipes_enabled((1 << GZP_PAIRING_PIPE)); + + gzll_rx_start(); + + while (nrf_gzll_is_enabled()) + { + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE)) + { + (void)nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, &gzp_req[0], &rx_payload_length); + + // Validate step 1 of pairing request + if (gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH) + { + gzp_address_exchanged_f = true; + } + } + } + + gzll_tx_fifo_flush(); + gzll_rx_fifo_flush(); + + gzll_set_rx_timeout(0); + + (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes); + + // Return to normal operation + gzll_rx_start(); + } + else + { + (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE)); + + gzll_set_rx_timeout(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT); + + // Start "not proximity" backoff period + gzll_rx_start(); + } +} + +static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe) +{ + gzll_goto_idle(); + + gzll_tx_fifo_flush(); + + (void)nrf_gzll_add_packet_to_tx_fifo(pipe, src, length); + + gzll_rx_start(); +} + +static void gzll_set_rx_timeout(uint32_t timeout) +{ + timeout *= 2; // * 2 as gzll_set_rx_timeout() takes RX_PERIODS as input, which equals 2 timeslots. + nrf_gzll_set_auto_disable(timeout); +} + +bool gzp_address_exchanged() +{ + return gzp_address_exchanged_f; +} + +#ifndef GZP_CRYPT_DISABLE + +bool gzp_crypt_user_data_received() +{ + return (gzp_encrypted_user_data_length > 0); +} + +bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length) +{ + if (gzp_encrypted_user_data_length > 0) + { + memcpy(dst, (void*)gzp_encrypted_user_data, gzp_encrypted_user_data_length); + + if (length != NULL) + { + *length = gzp_encrypted_user_data_length; + } + gzp_encrypted_user_data_length = 0; + + return true; + } + else + { + return false; + } +} + +static void gzp_session_counter_inc() +{ + uint8_t i; + + for (i = 0; i < GZP_SESSION_TOKEN_LENGTH; i++) + { + gzp_session_counter[i]++; + if (gzp_session_counter[i] != 0) + { + break; + } + } +} + +static void gzp_get_session_counter(uint8_t* dst) +{ + memcpy(dst, (void*)gzp_session_counter, GZP_SESSION_TOKEN_LENGTH); +} + +static void gzp_set_host_id(const uint8_t* src) +{ + if (*((uint8_t*)database) == 0xff) + { + nrf_nvmc_write_bytes(GZP_PARAMS_STORAGE_ADR + 1, src, GZP_HOST_ID_LENGTH); + nrf_nvmc_write_byte(GZP_PARAMS_STORAGE_ADR, 0x00); + } +} + +void gzp_get_host_id(uint8_t *dst) +{ + memcpy(dst, (uint8_t*)GZP_PARAMS_STORAGE_ADR + 1, GZP_HOST_ID_LENGTH); +} + +static void gzp_process_id_req(uint8_t* rx_payload) +{ + int i; + uint8_t temp_host_id[GZP_HOST_ID_LENGTH]; + + if (gzp_pairing_enabled_f) + { + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); + gzp_id_req_stat = GZP_ID_REQ_PENDING; + } + + gzp_get_host_id(temp_host_id); + + // Added: + for (i = 0; i < GZP_HOST_ID_LENGTH; i++) + { + if (temp_host_id[i] != 0xFF) + { + break; + } + } + + if (i == GZP_HOST_ID_LENGTH) // If host not generated yet + { + gzp_get_session_counter(temp_host_id); + +#if (GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); +#else //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_HOST_ID_LENGTH); +#endif //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + + gzp_set_host_id(temp_host_id); + } + } +} + +static void gzp_process_id_fetch(uint8_t* rx_payload) +{ + uint8_t tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH]; + + if (gzp_id_req_received()) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID])) + { + switch (gzp_id_req_stat) + { + case GZP_ID_REQ_PENDING_AND_GRANTED: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_GRANTED; + gzp_get_host_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]); + gzp_id_req_stat = GZP_ID_REQ_IDLE; + break; + case GZP_ID_REQ_PENDING_AND_REJECTED: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_REJECTED; + gzp_id_req_stat = GZP_ID_REQ_IDLE; + break; + case GZP_ID_REQ_PENDING: + default: + tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_PENDING; + break; + } + + tx_payload[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP; + gzp_add_validation_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]); + gzp_crypt(&tx_payload[1], &tx_payload[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); + + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzp_preload_ack(tx_payload, GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + } + } +} + +static void gzp_process_key_update_prepare() +{ + uint8_t tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH]; + + tx_payload[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP; + + gzp_get_session_counter(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + + // Update session token if no ID request is pending + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); + } + + gzp_preload_ack(tx_payload, GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); +} + +static void gzp_process_key_update(uint8_t* rx_payload) +{ + gzp_crypt_select_key(GZP_KEY_EXCHANGE); + gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID])) + { + gzp_crypt_set_dyn_key(&rx_payload[GZP_CMD_KEY_UPDATE_NEW_KEY]); + } +} + +static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) +{ + uint8_t tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH]; + + if (gzp_id_req_received()) + { + gzp_crypt_select_key(GZP_ID_EXCHANGE); + } + else + { + gzp_crypt_select_key(GZP_DATA_EXCHANGE); + } + + gzp_crypt(&rx_payload[1], &rx_payload[1], length - 1); + if (gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID])) + { + gzp_encrypted_user_data_length = length - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD; + memcpy((void*)gzp_encrypted_user_data, &rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], gzp_encrypted_user_data_length); + } + + // Build response packet + tx_payload[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP; + gzp_add_validation_id(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]); + gzp_crypt(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH); + gzp_get_session_counter(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + + // Update "session token" only if no ID request is pending + if (!gzp_id_req_received()) + { + gzp_crypt_set_session_token(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); + } + + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); + gzp_preload_ack(tx_payload, GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); +} + +//----------------------------------------------------------------------------- +// Function added during LE1 -> nRF51 port +//----------------------------------------------------------------------------- + +static void gzll_goto_idle() +{ + nrf_gzll_disable(); + while (nrf_gzll_is_enabled()) + {} +} + +static void gzll_tx_fifo_flush(void) +{ + int i; + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + (void)nrf_gzll_flush_tx_fifo(i); + } +} + +static void gzll_rx_fifo_flush(void) +{ + int i; + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + { + (void)nrf_gzll_flush_rx_fifo(i); + } +} + + +/******************************************************************************/ +// Implementation: Gazell callback functions +/******************************************************************************/ + +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ +} + + +void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) +{ +} + + +void nrf_gzll_disabled(void) +{ +} + + +void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) +{ + if (pipe == GZP_PAIRING_PIPE) + { + prev_gzp_rx_info = rx_info; + } +} + +/** @} */ +/** @} */ + +#endif diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c new file mode 100644 index 0000000..b78c34c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2009 - 2018, 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. + * + */ +#include "nrf_gzp.h" +#include "nrf_nvmc.h" + +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), nRF5x specific Host functions. + * @defgroup gzp_source_host_nrf5x Gazell Pairing Host nRF5x specific implementation + * @{ + * @ingroup gzp_04_source + */ + + +void gzp_host_chip_id_read(uint8_t *dst, uint8_t n) +{ + uint8_t i; + uint8_t random_number; + + if ( *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1)) == 0xff) + { + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) , 0x00); + + for (i = 0; i < n; i++) + { + gzp_random_numbers_generate(&random_number, 1); + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i) , random_number); + } + } + + for (i = 0; i < n; i++) + { + *(dst++) = *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i)); + } +} + +/** @} */ |