diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:08:59 +0200 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2018-08-23 17:12:21 +0200 |
commit | 3061ecca3d0fdfb87dabbf5f63c9e06c2a30f53a (patch) | |
tree | ab49cc16ed0b853452c5c2ed2d3042416d628986 /thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc | |
download | iot-sensors-master.tar.gz iot-sensors-master.tar.bz2 iot-sensors-master.tar.xz iot-sensors-master.zip |
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc')
71 files changed, 14049 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c new file mode 100644 index 0000000..58934c1 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c @@ -0,0 +1,205 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_AC_REC_PARSER) +#include "nfc_ac_rec_parser.h" +#include "sdk_macros.h" + +/** + * @brief Function for parsing Data Reference field inside Alternative Carrier record payload. + * + * This function parses Data Reference field inside Alternative Carrier record payload and extracts + * its descriptor. + * + * @param[in,out] pp_buff Pointer to pointer to the remaining payload data. + * @param[in,out] p_len Pointer to the length of remaining payload data. + * @param[in,out] p_ref_field Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NULL If provided buffer for Data Reference in \p p_ref_field is + * null. + * @retval NRF_ERROR_NO_MEM If the buffer provided for Data Reference in \p p_ref_field + * does not have enough space to store it. + * @retval NRF_ERROR_INVALID_LENGTH If Data Reference length exceeds record payload. + */ +static ret_code_t ac_rec_reference_field_parse(uint8_t ** const pp_buff, + uint32_t * const p_len, + nfc_ac_rec_data_ref_t * const p_ref_field) +{ + if (p_ref_field->length < **pp_buff) + { + return NRF_ERROR_NO_MEM; + } + p_ref_field->length = **pp_buff; + *pp_buff += AC_REC_DATA_REF_LEN_SIZE; + (*p_len) -= AC_REC_DATA_REF_LEN_SIZE; + + if (*p_len < p_ref_field->length) + { + return NRF_ERROR_INVALID_LENGTH; + } + VERIFY_PARAM_NOT_NULL(p_ref_field->p_data); + memcpy( p_ref_field->p_data, + *pp_buff, + p_ref_field->length ); + *pp_buff += p_ref_field->length; + (*p_len) -= p_ref_field->length; + + return NRF_SUCCESS; +} + +/** + * @brief Function for parsing Alternative Carrier record payload. + * + * This function parses Alternative Carrier record payload and extracts its payload descriptor. + * + * @param[in] p_buff Pointer to the record payload. + * @param[in] p_len Pointer to the record payload length. + * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in + * \p p_ac_rec_payload_data are nulls. + * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space + * to store its data. + * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload. + * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value. + */ +static ret_code_t nfc_ac_payload_parse(uint8_t * p_buff, + uint32_t * const p_len, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data) +{ + if ( (p_buff == NULL) || (p_len == NULL) || (p_ac_rec_payload_data == NULL) ) + { + return NRF_ERROR_NULL; + } + + if (*p_len < AC_REC_CPS_BYTE_SIZE + AC_REC_DATA_REF_LEN_SIZE + AC_REC_AUX_DATA_REF_COUNT_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Copy CPS to ac record payload descriptor. + if (*p_buff & ~NFC_AC_CPS_MASK) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_ac_rec_payload_data->cps = (nfc_ac_rec_cps_t) *p_buff; + p_buff += AC_REC_CPS_BYTE_SIZE; + (*p_len) -= AC_REC_CPS_BYTE_SIZE; + + // Copy Carrier Data Reference to ac record payload descriptor. + ret_code_t err_code = ac_rec_reference_field_parse(&p_buff, + p_len, + &p_ac_rec_payload_data->carrier_data_ref); + VERIFY_SUCCESS(err_code); + + // Copy Auxiliary Data Reference to ac record payload descriptor. + if ( p_ac_rec_payload_data->aux_data_ref_count < *p_buff) + { + return NRF_ERROR_NO_MEM; + } + p_ac_rec_payload_data->aux_data_ref_count = *p_buff; + p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE; + (*p_len) -= AC_REC_AUX_DATA_REF_COUNT_SIZE; + + if (p_ac_rec_payload_data->aux_data_ref_count != 0) + { + VERIFY_PARAM_NOT_NULL(p_ac_rec_payload_data->p_aux_data_ref); + } + + for (uint8_t i = 0; i < p_ac_rec_payload_data->aux_data_ref_count; i++) + { + err_code = ac_rec_reference_field_parse(&p_buff, + p_len, + &(p_ac_rec_payload_data->p_aux_data_ref[i])); + VERIFY_SUCCESS(err_code); + } + + // Check if all payload data were parsed. + if (*p_len != 0) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return NRF_SUCCESS; +} + +ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data) +{ + ret_code_t err_code; + + if (p_rec_desc->tnf != TNF_WELL_KNOWN) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->type_length != sizeof(nfc_ac_rec_type_field)) + { + return NRF_ERROR_INVALID_DATA; + } + + if (memcmp(p_rec_desc->p_type, nfc_ac_rec_type_field, sizeof(nfc_ac_rec_type_field)) != 0) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t const * p_payload = + ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->p_payload; + uint32_t payload_length = + ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->payload_length; + + err_code = nfc_ac_payload_parse((uint8_t *) p_payload, + &payload_length, + p_ac_rec_payload_data); + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_AC_REC_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h new file mode 100644 index 0000000..998084f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h @@ -0,0 +1,88 @@ +/** + * 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 + * + * @defgroup nfc_ac_rec_parser Alternative Carrier records parser + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding Alternative Carrier records. + */ + +#ifndef __NFC_AC_REC_PARSER_H__ +#define __NFC_AC_REC_PARSER_H__ + +#include "nfc_ndef_record.h" +#include "nfc_ac_rec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for parsing general record description as Alternative Carrier record. + * + * This function checks if record description matches the Alternative Carrier record and extracts + * its payload structure. It is required for the record description to use binary payload + * descriptor. + * + * @param[in] p_rec_desc Pointer to the record descriptor. + * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect. + * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary. + * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in + * \p p_ac_rec_payload_data are nulls. + * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space + * to store its data. + * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload. + * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value. + */ +ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data); + +#ifdef __cplusplus +} +#endif + +#endif // __NFC_AC_REC_PARSER_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c new file mode 100644 index 0000000..41ec302 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c @@ -0,0 +1,524 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA_PARSER) +#include "nfc_ble_oob_advdata_parser.h" +#include "app_util.h" +#include "nfc_ble_pair_common.h" + +#define NRF_LOG_MODULE_NAME ble_oob_ad_parser +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +/* Workaround for using NRF_LOG_RAW_INFO() macro only when logging level is "DEBUG" */ +#if (NRF_LOG_LEVEL > 3) +#define NRF_BLE_OOB_AD_PARSER_LOG_DEBUG(...) NRF_LOG_RAW_INFO(__VA_ARGS__) +#else // (NRF_LOG_LEVEL > 3) +#define NRF_BLE_OOB_AD_PARSER_LOG_DEBUG(...) +#endif // (NRF_LOG_LEVEL > 3) + +#define EARLY_TERMINATOR 0 /* Value of AD Structure Length field indicating an early + termination of Advertising or Scan Response Data. */ +#define FIELD_LEN_INC_VAL 1 /* Incorrect Value of AD Structure Length field. */ + +/** @brief Values used with @ref ad_type_counter_t. */ +typedef enum +{ + AD_TYPE_NOT_PRESENT = 0, /* Value indicating that AD type is not present. */ + AD_TYPE_OCCUR_THRES = 1 /* Maximal occurrence number of any AD type within the buffer */ +} ad_type_counter_values_t; + +/**@brief Internal module structure indicating how many BLE AD fields of the same type are in the buffer. */ +typedef struct +{ + uint8_t name_type; /* Number of Short and Full Device Name AD Structures. */ + uint8_t addr_type; /* Number of LE Bluetooth Device Address AD Structures. */ + uint8_t appear_type; /* Number of Appearance AD Structures. */ + uint8_t flags_type; /* Number of Flags AD Structures. */ + uint8_t le_role_type; /* Number of LE Role AD Structures. */ + uint8_t tk_type; /* Number of Security Manager TK AD Structures. */ + uint8_t sec_mgr_oob_flags_type; /* Number of Security Manager OOB Flags AD Structures. */ + uint8_t lesc_confirm_type; /* Number of LESC OOB Confirmation Value AD Structures. */ + uint8_t lesc_random_type; /* Number of LESC OOB Random Value AD Structures. */ +} ad_type_counter_t; + +/**@brief Decodes and stores AD Data from Flags AD Structure. */ +__STATIC_INLINE ret_code_t flags_decode(uint8_t const * p_flags_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_FLAGS_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_nfc_ble_pairing_data->flags = *p_flags_data; + + return NRF_SUCCESS; +} + +void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data) +{ + NRF_LOG_RAW_INFO("\r\n"); + NRF_LOG_INFO("BLE Advertising data contents"); + NRF_LOG_INFO("Device name: \"%s\"", NRF_LOG_PUSH((char *)p_pairing_data->device_name.p_name)); + NRF_LOG_INFO("Device Address: "); + + for (int i=0; i < BLE_GAP_ADDR_LEN; ++i) + { + NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_device_addr->addr[i]); + } + NRF_LOG_RAW_INFO("\r\n"); + + if (p_pairing_data->p_tk_value != NULL) + { + NRF_LOG_INFO("Device Temporary Key present."); + for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_tk_value->tk[i]); + } + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n"); + } + else + { + NRF_LOG_INFO("Device Temporary Key not present."); + } + + if (p_pairing_data->p_lesc_confirm_value != NULL && p_pairing_data->p_lesc_random_value) + { + NRF_LOG_INFO("LESC Confirmation Value present."); + for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_lesc_confirm_value[i]); + } + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n"); + + NRF_LOG_INFO("LESC Random Value present."); + for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i) + { + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_lesc_random_value[i]); + } + NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n"); + } + else + { + NRF_LOG_INFO("LESC data not present."); + } + + NRF_LOG_RAW_INFO("\r\n"); +} + +/**@brief Decodes and stores AD Data that is common for Short and Full Device Name AD Structures. */ +static ret_code_t name_decode(uint8_t const * p_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + uint8_t * p_name = p_nfc_ble_pairing_data->device_name.p_name; + uint8_t * p_name_len = &p_nfc_ble_pairing_data->device_name.len; + + VERIFY_PARAM_NOT_NULL(p_name); + if (*p_name_len < len) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_name, p_name_data, len); + *p_name_len = len; + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Short Device Name AD Structure. */ +__STATIC_INLINE ret_code_t short_name_decode(uint8_t const * p_short_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_SHORT_NAME; + + return name_decode(p_short_name_data, len, p_nfc_ble_pairing_data); +} + +/**@brief Decodes and stores AD Data from Full Device Name AD Structure. */ +__STATIC_INLINE ret_code_t full_name_decode(uint8_t const * p_full_name_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_FULL_NAME; + + return name_decode(p_full_name_data, len, p_nfc_ble_pairing_data); +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t tk_value_decode(uint8_t const * p_tk_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_TK_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ble_advdata_tk_value_t * p_tk_value = p_nfc_ble_pairing_data->p_tk_value; + VERIFY_PARAM_NOT_NULL(p_tk_value); + + memcpy(p_tk_value->tk, p_tk_value_data, AD_TYPE_TK_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t lesc_confirm_value_decode(uint8_t const * p_lesc_confirm_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_CONFIRM_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t * p_lesc_confirm_data = p_nfc_ble_pairing_data->p_lesc_confirm_value; + VERIFY_PARAM_NOT_NULL(p_lesc_confirm_data); + + memcpy(p_lesc_confirm_data, p_lesc_confirm_value_data, AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */ +static ret_code_t lesc_random_value_decode(uint8_t const * p_lesc_random_value_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_RANDOM_VALUE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t * p_lesc_random_data = p_nfc_ble_pairing_data->p_lesc_random_value; + VERIFY_PARAM_NOT_NULL(p_lesc_random_data); + + memcpy(p_lesc_random_data, p_lesc_random_value_data, AD_TYPE_RANDOM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Security Manager OOB Flags AD Structure. */ +static ret_code_t sec_mgr_oob_flags_decode(uint8_t const * p_sec_mgr_oob_flags_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_OOB_FLAGS_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + VERIFY_PARAM_NOT_NULL(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags); + *(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags) = *(p_sec_mgr_oob_flags_data); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from Appearance AD Structure. */ +static ret_code_t appearance_decode(uint8_t const * p_appearance_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_APPEARANCE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_nfc_ble_pairing_data->appearance = uint16_decode(p_appearance_data); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from LE Bluetooth Device Address AD Structure. */ +static ret_code_t ble_device_addr_decode(uint8_t const * p_dev_addr_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + ble_gap_addr_t * p_device_addr = p_nfc_ble_pairing_data->p_device_addr; + VERIFY_PARAM_NOT_NULL(p_device_addr); + + memcpy(p_device_addr->addr, p_dev_addr_data, BLE_GAP_ADDR_LEN); + p_device_addr->addr_type = *(p_dev_addr_data + BLE_GAP_ADDR_LEN); + + return NRF_SUCCESS; +} + +/**@brief Decodes and stores AD Data from LE Role AD Structure. */ +static ret_code_t le_role_decode(uint8_t const * p_le_role_data, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + if (len != AD_TYPE_LE_ROLE_DATA_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + uint8_t le_role = *p_le_role_data; + switch (le_role) + { + case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_CENTRAL; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED; + break; + + case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED: + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + +/**@brief Validates if Length field of AD structure is correct. */ +__STATIC_INLINE ret_code_t field_length_validate(uint8_t field_length, uint8_t index, uint8_t len) +{ + if ( (field_length == FIELD_LEN_INC_VAL) || (index + field_length >= len) ) + { + return NRF_ERROR_INVALID_LENGTH; + } + else + { + return NRF_SUCCESS; + } +} + +/**@brief Validates which AD types were not present in parsed data and checks if any + * AD Type occured more than once. + */ +__STATIC_INLINE ret_code_t field_type_validate(nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data, + ad_type_counter_t * ad_type_counter) +{ + /* Reset AD type fields which were not present in parsed buffer. */ + if (ad_type_counter->name_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->device_name.p_name = NULL; + p_nfc_ble_pairing_data->device_name.len = 0; + p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_NO_NAME; + } + if ( (ad_type_counter->addr_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_device_addr != NULL) ) + { + p_nfc_ble_pairing_data->p_device_addr = NULL; + } + if ( (ad_type_counter->tk_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_tk_value != NULL) ) + { + p_nfc_ble_pairing_data->p_tk_value = NULL; + } + if ( (ad_type_counter->lesc_confirm_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_lesc_confirm_value != NULL) ) + { + p_nfc_ble_pairing_data->p_lesc_confirm_value = NULL; + } + if ( (ad_type_counter->lesc_random_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_lesc_random_value != NULL) ) + { + p_nfc_ble_pairing_data->p_lesc_random_value = NULL; + } + if ( (ad_type_counter->sec_mgr_oob_flags_type == AD_TYPE_NOT_PRESENT) && + (p_nfc_ble_pairing_data->p_sec_mgr_oob_flags != NULL) ) + { + p_nfc_ble_pairing_data->p_sec_mgr_oob_flags = NULL; + } + if (ad_type_counter->appear_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->appearance = BLE_ADVDATA_APPEARANCE_NOT_PRESENT; + } + if (ad_type_counter->flags_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->flags = 0; + } + if (ad_type_counter->le_role_type == AD_TYPE_NOT_PRESENT) + { + p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_NOT_PRESENT; + } + + /* Check if any AD Type was doubled. */ + if ( (ad_type_counter->name_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->addr_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->tk_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->sec_mgr_oob_flags_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->appear_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->flags_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->le_role_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->lesc_confirm_type > AD_TYPE_OCCUR_THRES) || + (ad_type_counter->lesc_random_type > AD_TYPE_OCCUR_THRES) ) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + +ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t index = 0; + + ad_type_counter_t ad_type_counter; + memset(&ad_type_counter, AD_TYPE_NOT_PRESENT, sizeof(ad_type_counter_t)); + + if ( (p_nfc_ble_pairing_data == NULL) || (p_advdata == NULL) ) + { + return NRF_ERROR_NULL; + } + + while (index < len) + { + uint8_t field_length = p_advdata[index]; + if (field_length == EARLY_TERMINATOR) + { + return NRF_SUCCESS; + } + err_code = field_length_validate(field_length, index, len); + VERIFY_SUCCESS(err_code); + + uint8_t field_type = p_advdata[index + AD_LENGTH_FIELD_SIZE]; + uint8_t const * p_field_data = &p_advdata[index + AD_DATA_OFFSET]; + uint8_t field_data_len = field_length - AD_TYPE_FIELD_SIZE; + + switch (field_type) + { + case BLE_GAP_AD_TYPE_FLAGS: + ++ad_type_counter.flags_type; + err_code = flags_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME: + ++ad_type_counter.name_type; + err_code = short_name_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME: + ++ad_type_counter.name_type; + err_code = full_name_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE: + ++ad_type_counter.tk_type; + err_code = tk_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE: + ++ad_type_counter.lesc_confirm_type; + err_code = lesc_confirm_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE: + ++ad_type_counter.lesc_random_type; + err_code = lesc_random_value_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS: + ++ad_type_counter.sec_mgr_oob_flags_type; + err_code = sec_mgr_oob_flags_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_APPEARANCE: + ++ad_type_counter.appear_type; + err_code = appearance_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS: + ++ad_type_counter.addr_type; + err_code = ble_device_addr_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + case BLE_GAP_AD_TYPE_LE_ROLE: + ++ad_type_counter.le_role_type; + err_code = le_role_decode(p_field_data, + field_data_len, + p_nfc_ble_pairing_data); + break; + + default: + /* AD Structure Type field unknown for parser. */ + return NRF_ERROR_NOT_SUPPORTED; + } + + VERIFY_SUCCESS(err_code); + + index += field_length + AD_LENGTH_FIELD_SIZE; + } + + err_code = field_type_validate(p_nfc_ble_pairing_data, &ad_type_counter); + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h new file mode 100644 index 0000000..6168e98 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h @@ -0,0 +1,137 @@ +/** + * 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 + * + * @defgroup nfc_ble_oob_advdata_parser Advertising and Scan Response Data Parser for NFC OOB pairing + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding data in the Advertising and Scan Response + * Data format for NFC OOB pairing. + */ + +#ifndef NFC_BLE_OOB_ADVDATA_PARSER_H_ +#define NFC_BLE_OOB_ADVDATA_PARSER_H_ + +#include "sdk_errors.h" +#include "ble_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_ADVDATA_APPEARANCE_NOT_PRESENT 0 /**< Appearance AD structure not present. */ + +/**@brief Bluetooth Low Energy GAP device name. */ +typedef struct +{ + ble_advdata_name_type_t name_type; /**< See @ref ble_advdata_name_type_t. */ + uint8_t len; /**< Length of device name. */ + uint8_t * p_name; /**< Pointer to the buffer with device name. */ +} ble_gap_dev_name_t; + +/**@brief BLE Advertising data that is relevant for OOB pairing. */ +typedef struct +{ + ble_gap_dev_name_t device_name; /**< See @ref ble_gap_dev_name_t. */ + ble_gap_addr_t * p_device_addr; /**< See @ref ble_gap_addr_t. */ + ble_advdata_tk_value_t * p_tk_value; /**< See @ref ble_advdata_tk_value_t. */ + uint8_t * p_lesc_confirm_value; /**< LESC OOB confirmation data. */ + uint8_t * p_lesc_random_value; /**< LESC OOB random data. */ + ble_advdata_le_role_t le_role; /**< See @ref ble_advdata_le_role_t. */ + uint16_t appearance; /**< Advertising data Appearance field. */ + uint8_t flags; /**< Advertising data Flags field. */ + uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags data field. */ +} nfc_ble_oob_pairing_data_t; + +/**@brief Function for parsing BLE data encoded in AD Type format. + * + * @details This function parses BLE data encoded in Advertising Data Type format which + * can be generated with @ref ble_advdata_encode function. The result of the parsing is + * stored within @ref nfc_ble_oob_pairing_data_t structure. + * + * @note Currently, module can be used to parse BLE AD Type data, which contains + * AD Structures with following GAP AD Types: Flags, Shortened and Complete Device + * Name, Security Manager TK Value and OOB Flags, Appearance, LE Bluetooth Device + * Address and LE Role. + * + * @warning Before passing \p p_nfc_ble_pairing_data structure to this function, + * it is necessary to provide buffers for AD Structures Data, which are expected to be + * found within parsed buffer. This applies to following GAP AD Types with corresponding + * structures: Shortened and Complete Device Name - @ref ble_gap_dev_name_t, + * LE Bluetooth Device Address - @ref ble_gap_addr_t, Security Manager TK Value - + * @ref ble_advdata_tk_value_t and Security Manager OOB Flags - uint8_t. + * + * @param[in] p_advdata Pointer to the data to be parsed. + * @param[in] len Size of the data to be parsed. + * @param[out] p_nfc_ble_pairing_data Pointer to the structure that will be used + * to hold parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer for device name is + * too small to hold parsed data. + * @retval NRF_ERROR_INVALID_LENGTH If any AD Structure Length field contains + * different value than expected. + * @retval NRF_ERROR_INVALID_PARAM If any AD Structure Data field contains + * invalid parameters. + * @retval NRF_ERROR_NULL If any function pointer parameter is NULL or + * any expected buffer in \p p_nfc_ble_pairing_data + * was not provided. + * @retval NRF_ERROR_NOT_SUPPORTED If any AD Structure Type field contains + * type which is not supported or any AD + * Structure Type occurs more than once. + */ +ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata, + uint8_t len, + nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data); + + +/**@brief Function for displaying values of basic BLE OOB Advertising data types. + * + * @param[in] p_pairing_data Structure containing parsed data. + */ +void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data); + +#ifdef __cplusplus +} +#endif + +#endif //NFC_BLE_OOB_ADVDATA_PARSER_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c new file mode 100644 index 0000000..98ea901 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c @@ -0,0 +1,104 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_LE_OOB_REC_PARSER) +#include "nfc_le_oob_rec_parser.h" +#include "sdk_errors.h" + +/** + * @brief Function for parsing LE OOB record payload. + * + * This function parses LE OOB record payload and extracts BLE OOB Advertising data structure. + * + * @param[in] p_buff Pointer to the record payload. + * @param[in] p_len Pointer to the record payload length. + * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval Other An error code that might have been returned by + * @ref nfc_ble_oob_advdata_parse function. + */ +static ret_code_t nfc_le_oob_payload_parse(uint8_t * p_buff, + uint32_t * const p_len, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data) +{ + ret_code_t err_code = nfc_ble_oob_advdata_parse(p_buff, + *p_len, + p_nfc_ble_oob_pairing_data); + return err_code; +} + +ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data) +{ + ret_code_t err_code; + + if (p_rec_desc->tnf != TNF_MEDIA_TYPE) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->type_length != sizeof(le_oob_rec_type_field)) + { + return NRF_ERROR_INVALID_DATA; + } + + if (memcmp(p_rec_desc->p_type, le_oob_rec_type_field, sizeof(le_oob_rec_type_field)) != 0) + { + return NRF_ERROR_INVALID_DATA; + } + + if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t const * p_payload = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->p_payload; + uint32_t payload_lenght = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->payload_length; + + err_code = nfc_le_oob_payload_parse((uint8_t *) p_payload, + &payload_lenght, + p_nfc_ble_oob_pairing_data); + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_LE_OOB_REC_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h new file mode 100644 index 0000000..0df5657 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h @@ -0,0 +1,85 @@ +/** + * 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 + * + * @defgroup nfc_le_oob_rec_parser LE OOB records parser + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Functions for parsing and decoding LE OOB records. + */ + +#ifndef __NFC_LE_OOB_REC_PARSER_H__ +#define __NFC_LE_OOB_REC_PARSER_H__ + +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata_parser.h" +#include "nfc_ble_pair_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for parsing general record description as LE OOB record. + * + * This function checks if record description matches the LE OOB record pattern and extracts BLE + * OOB Advertising data structure. It is required for the record description to use binary payload + * descriptor. + * + * @param[in] p_rec_desc Pointer to the record descriptor. + * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold + * parsed data. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect. + * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary. + * @retval Other An error code that might have been returned by + * @ref nfc_ble_oob_advdata_parse function. + */ +ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc, + nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data); + +#ifdef __cplusplus +} +#endif + +#endif // __NFC_LE_OOB_REC_PARSER_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c new file mode 100644 index 0000000..c4cdabe --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c @@ -0,0 +1,164 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_AC_REC) + +#include "nfc_ac_rec.h" +#include <string.h> +#include "nrf_error.h" +#include "nrf.h" + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +const uint8_t nfc_ac_rec_type_field[2] = {'a', 'c'}; ///< Alternative Carrier Record type. + +/** + * @brief Function for calculating the payload length of the NFC NDEF Alternative Carrier record. + */ +static uint32_t nfc_ac_rec_payload_size_get(nfc_ac_rec_payload_desc_t const * p_ac_rec_payload_desc) +{ + int32_t i = 0; + // Initialize with size of byte with CPS. + uint32_t payload_size = AC_REC_CPS_BYTE_SIZE; + + // Add Carrier Data Reference size. + payload_size += p_ac_rec_payload_desc->carrier_data_ref.length + AC_REC_DATA_REF_LEN_SIZE; + + // Add Auxiliary Data Reference Count size. + payload_size += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_ac_rec_payload_desc->aux_data_ref_count; i++) + { + // Add Auxiliary Data Reference size. + payload_size += p_ac_rec_payload_desc->p_aux_data_ref[i].length + AC_REC_DATA_REF_LEN_SIZE; + } + + return payload_size; +} + + +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + int32_t i = 0; + uint32_t payload_size = nfc_ac_rec_payload_size_get(p_nfc_rec_ac_payload_desc); + + if (p_buff != NULL) + { + // Not enough space in the buffer, return an error. + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + // Invalid CPS value. + if ( p_nfc_rec_ac_payload_desc->cps & ~NFC_AC_CPS_MASK ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Copy CPS. + *p_buff = p_nfc_rec_ac_payload_desc->cps; + p_buff += AC_REC_CPS_BYTE_SIZE; + + // Copy Carrier Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->carrier_data_ref.p_data, + p_nfc_rec_ac_payload_desc->carrier_data_ref.length ); + p_buff += p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + + // Copy Auxiliary Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->aux_data_ref_count; + p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_nfc_rec_ac_payload_desc->aux_data_ref_count; i++) + { + *p_buff = p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].p_data, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length ); + p_buff += p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + } + } + + // Assign payload size to the return buffer. + *p_len = payload_size; + + return NRF_SUCCESS; +} + + +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t*)p_ac_rec->p_payload_descriptor; + + p_ac_rec_payload->aux_data_ref_count = 0; +} + + +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t *)p_ac_rec->p_payload_descriptor; + + if (p_ac_rec_payload->aux_data_ref_count >= p_ac_rec_payload->max_aux_data_ref) + { + return NRF_ERROR_NO_MEM; + } + + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].p_data = p_aux_data; + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].length = aux_length; + p_ac_rec_payload->aux_data_ref_count++; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_AC_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h new file mode 100644 index 0000000..d748d2a --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h @@ -0,0 +1,199 @@ +/** + * 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 NFC_AC_REC_H__ +#define NFC_AC_REC_H__ + +/**@file + * + * @defgroup nfc_ac_rec ac (Alternative carrier) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Alternative Carrier records for NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +/** + * @brief Carrier Power State. + * + * Possible Carrier Power State field values in an Alternative Carrier record. + */ +typedef enum +{ + NFC_AC_CPS_INACTIVE = 0x00, ///< Alternative Carrier inactive. + NFC_AC_CPS_ACTIVE = 0x01, ///< Alternative Carrier active. + NFC_AC_CPS_ACTIVATING = 0x02, ///< Alternative Carrier activating. + NFC_AC_CPS_UNKNOWN = 0x03 ///< Alternative Carrier power status unknown. +} nfc_ac_rec_cps_t; + +#define NFC_AC_CPS_MASK (NFC_AC_CPS_UNKNOWN) ///< Mask of Carrier Power State bits in a first ac record byte. + +/** + * @brief Carrier Data Reference and Auxiliary Data Reference descriptor. + */ +typedef struct +{ + uint8_t length; ///< Length of the data field. + uint8_t * p_data; ///< Pointer to the Data Reference characters. Not relevant if length is 0. +} nfc_ac_rec_data_ref_t; + +/** + * @brief Alternative Carrier record payload descriptor. + */ +typedef struct +{ + nfc_ac_rec_cps_t cps; ///< Carrier Power State value. + nfc_ac_rec_data_ref_t carrier_data_ref; ///< Carrier Data Reference. + uint8_t const max_aux_data_ref; ///< Maximum number of Auxiliary Data Reference fields. + uint8_t aux_data_ref_count; ///< Number of Auxiliary Data Reference fields. + nfc_ac_rec_data_ref_t * p_aux_data_ref; ///< Pointer to the Auxiliary Data Reference fields. +} nfc_ac_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Alternative Carrier record payload. + * + * This function encodes the payload of an Alternative Carrier record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_ac_rec_type_field[2]; + +/** + * @brief Size of the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +#define NFC_AC_REC_TYPE_LENGTH 2 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for an Alternative Carrier record. + * + * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and + * an instance of type @ref nfc_ac_rec_payload_desc_t, which together constitute an instance of an Alternative Carrier record. + * + * Use the macro @ref NFC_NDEF_AC_RECORD_DESC to access the NDEF Alternative Carrier record descriptor instance. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_ble_full_handover_select_msg_encode) + * must be done in the same variable scope. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] CPS Carrier Power State value. + * @param[in] CARR_DATA_REF_LEN Length of the Carrier Data Reference field. + * @param[in] P_CARR_DATA_REF Pointer to the Carrier Data Reference field. + * @param[in] MAX_AUX_DATA_REF Maximum number of Auxiliary Data Reference fields. + */ +#define NFC_NDEF_AC_RECORD_DESC_DEF(NAME, \ + CPS, \ + CARR_DATA_REF_LEN, \ + P_CARR_DATA_REF, \ + MAX_AUX_DATA_REF) \ + nfc_ac_rec_data_ref_t NAME##_nfc_ac_rec_aux_data_ref_array[MAX_AUX_DATA_REF]; \ + nfc_ac_rec_payload_desc_t NAME##_nfc_ac_rec_payload_desc = \ + { \ + .cps = CPS, \ + .carrier_data_ref = {CARR_DATA_REF_LEN, P_CARR_DATA_REF}, \ + .max_aux_data_ref = MAX_AUX_DATA_REF, \ + .aux_data_ref_count = 0, \ + .p_aux_data_ref = NAME##_nfc_ac_rec_aux_data_ref_array \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_ac_rec_type_field, \ + NFC_AC_REC_TYPE_LENGTH, \ + nfc_ac_rec_payload_constructor, \ + &(NAME##_nfc_ac_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Alternative Carrier record descriptor + * instance that was created with @ref NFC_NDEF_AC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_AC_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing an Auxiliary Data Reference in an NFC NDEF Alternative Carrier record. + * + * This function clears the Auxiliary Data References from the Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to the Alternative Carrier record descriptor. + */ +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec); + +/** + * @brief Function for adding an Auxiliary Data Reference to an NFC NDEF Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to an ac record. + * @param[in] p_aux_data Pointer to the Auxiliary Data Reference data buffer. + * @param[in] aux_length Length of the Auxiliary Data Reference data. + * + * @retval NRF_SUCCESS If the Auxiliary Data Reference was added successfully. + * @retval NRF_ERROR_NO_MEM If the record already contains the maximum number of Auxiliary Data References. + */ +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_AC_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c new file mode 100644 index 0000000..588c504 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c @@ -0,0 +1,402 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA) + +#include "nfc_ble_oob_advdata.h" +#include "sdk_common.h" +#include "nfc_ble_pair_msg.h" +#include "nfc_ble_pair_common.h" + + +/** + * @brief Macro for verifying basic parameters used for encoding single BLE AD Type. + * + * It verifies if provided buffer is NULL and if there is enough space for the encoded data. + * In case of NULL pointer buffer, necessary space for current AD Type is calculated. + * + * @param[in] P_ENCODED_DATA Buffer for the encoded data. + * @param[in] P_OFFSET Pointer to index of the first free cell in the buffer. + * @param[in] AD_TYPE_SIZE Size of the single AD Type. + * @param[in] MAX_SIZE Maximal size of the provided buffer. + */ +#define NFC_BLE_OOB_ADVDATA_INPUT_VERIFY( P_ENCODED_DATA, P_OFFSET, AD_TYPE_SIZE, MAX_SIZE) \ + if ( (P_ENCODED_DATA) == NULL ) \ + { \ + *(P_OFFSET) += (AD_TYPE_SIZE); \ + return NRF_SUCCESS; \ + } \ + if ( *(P_OFFSET) + (AD_TYPE_SIZE) > (MAX_SIZE) ) \ + { \ + return NRF_ERROR_DATA_SIZE; \ + } + +/**@brief Function for encoding data of Security Manager OOB Flags AD Type. + * + * @param[in] oob_flags Security Manager OOB Flags AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t sec_mgr_oob_flags_encode(uint8_t oob_flags, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_OOB_FLAGS_SIZE, max_size); + + // Encode flags. + p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE); + *p_offset += AD_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS; + *p_offset += AD_TYPE_FIELD_SIZE; + p_encoded_data[*p_offset] = oob_flags; + *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding data of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_TK_VALUE_SIZE, max_size); + + // Encode TK Value. + p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE); + *p_offset += AD_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE; + *p_offset += AD_TYPE_FIELD_SIZE; + + // Remember location of TK in the buffer if this feature was enabled. + err_code = nfc_tk_to_group_add(&p_encoded_data[*p_offset]); + VERIFY_SUCCESS(err_code); + + nfc_tk_value_payload_encode(p_tk_value, &p_encoded_data[*p_offset]); + (*p_offset) += AD_TYPE_TK_VALUE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding LESC OOB data in the CH NDEF message. + * + * @param[in] p_lesc_value Pointer to the LESC OOB values to be encoded. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t lesc_value_encode(ble_gap_lesc_oob_data_t * p_lesc_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LESC_SIZE, max_size); + + // Encode LESC Confirm Value. + p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + *p_offset += AD_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE; + *p_offset += AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->c, sizeof(p_lesc_value->c)); + + uint8_t *p_confirm = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_CONFIRM_VALUE_DATA_SIZE; + + // Encode LESC Random Value. + p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_RANDOM_VALUE_DATA_SIZE); + *p_offset += AD_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE; + *p_offset += AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->r, sizeof(p_lesc_value->r)); + + uint8_t *p_random = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_RANDOM_VALUE_DATA_SIZE; + + // Remember location of LESC OOB data in the buffer in case of key changes. + err_code = nfc_lesc_pos_set(p_confirm, p_random); + + return err_code; +} + +/**@brief Function for encoding data of LE Role AD Type. + * + * @param[in] le_role LE Role AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + * @retval NRF_ERROR_INVALID_PARAM If \p le_role parameter has invalid value. + */ +static ret_code_t le_role_encode(ble_advdata_le_role_t le_role, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LE_ROLE_SIZE, max_size); + + // Encode LE Role. + p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE); + *p_offset += AD_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE; + *p_offset += AD_TYPE_FIELD_SIZE; + switch (le_role) + { + case BLE_ADVDATA_ROLE_ONLY_PERIPH: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH; + break; + case BLE_ADVDATA_ROLE_ONLY_CENTRAL: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL; + break; + case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED; + break; + case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED; + break; + default: + return NRF_ERROR_INVALID_PARAM; + } + *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for calculating the size of Local Name AD Type. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode Local Name AD Type. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref sd_ble_gap_device_name_get function. + */ +__STATIC_INLINE ret_code_t nfc_ble_oob_name_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t device_len; + + if (p_advdata->name_type == BLE_ADVDATA_SHORT_NAME) + { + device_len = p_advdata->short_name_len; + } + else + { + err_code = sd_ble_gap_device_name_get(NULL, &device_len); + } + + *p_len += AD_LENGTH_FIELD_SIZE + AD_TYPE_FIELD_SIZE + device_len; + return err_code; +} + +/**@brief Function for calculating the size of AD Types which are encoded by @ref ble_advdata_encode function. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode AD Types. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref nfc_ble_oob_name_size_calc function. + */ +static ret_code_t nfc_ble_oob_adv_data_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_advdata->include_ble_device_addr) + { + *p_len += AD_TYPE_BLE_DEVICE_ADDR_SIZE; + } + if (p_advdata->include_appearance) + { + *p_len += AD_TYPE_APPEARANCE_SIZE; + } + if (p_advdata->flags != 0) + { + *p_len += AD_TYPE_FLAGS_SIZE; + } + if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) + { + err_code = nfc_ble_oob_name_size_calc(p_advdata, p_len); + } + return err_code; +} + +#if ADVANCED_ADVDATA_SUPPORT == 0 +/**@brief Function for verifying if BLE advertising data structure contains only supported AD Types + * by this encoding module. + * + * @param[in] advdata Structure with BLE advertising data. + * + * @retval NRF_SUCCESS If the verification was successful. + * @retval NRF_ERROR_INVALID_PARAM If there is any AD type which is not supported by this + * module. + */ +static ret_code_t nfc_ble_oob_adv_data_check(ble_advdata_t advdata) +{ + advdata.p_sec_mgr_oob_flags = NULL; + advdata.p_tk_value = NULL; + advdata.le_role = BLE_ADVDATA_ROLE_NOT_PRESENT; + advdata.include_ble_device_addr = false; + advdata.include_appearance = false; + advdata.flags = 0; + advdata.name_type = BLE_ADVDATA_NO_NAME; + advdata.short_name_len = 0; + advdata.p_lesc_data = NULL; + + ble_advdata_t pattern_advdata; + memset(&pattern_advdata, 0, sizeof(ble_advdata_t)); + + if ( memcmp( &pattern_advdata, &advdata, sizeof(ble_advdata_t)) == 0 ) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } +} +#endif //ADVANCED_ADVDATA_SUPPORT + +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t max_size = *p_len; + uint16_t offset = 0; + +#if ADVANCED_ADVDATA_SUPPORT + // In this mode, you cannot count the NDEF message length. + VERIFY_FALSE(p_encoded_data == NULL, NRF_ERROR_INVALID_PARAM); +#else + // Verify ADV data structure. + err_code = nfc_ble_oob_adv_data_check(*p_advdata); + VERIFY_SUCCESS(err_code); +#endif //ADVANCED_ADVDATA_SUPPORT + + // Encode Security Manager OOB Flags. + if (p_advdata->p_sec_mgr_oob_flags != NULL) + { + err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, + p_encoded_data, + &offset, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LESC keys + if (p_advdata->p_lesc_data != NULL) + { + err_code = lesc_value_encode(p_advdata->p_lesc_data, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Security Manager TK value. + if (p_advdata->p_tk_value != NULL) + { + err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LE Role. + if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) + { + err_code = le_role_encode(p_advdata->le_role, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode remaining AD Types or precalculate necessary buffer space. + if (p_encoded_data != NULL) + { + uint16_t adv_data_size = max_size - offset; + err_code = ble_advdata_encode(p_advdata, p_encoded_data + offset, &adv_data_size); + *p_len = offset + adv_data_size; + } + else + { + err_code = nfc_ble_oob_adv_data_size_calc(p_advdata, &offset); + *p_len = offset; + } + + return err_code; +} + +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data) +{ + for (uint8_t i = 0; i < AD_TYPE_TK_VALUE_DATA_SIZE; i++) + { + *(p_tk_payload_data++) = p_tk_value->tk[i]; + } +} + +#endif // NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h new file mode 100644 index 0000000..650b129 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h @@ -0,0 +1,94 @@ +/** + * 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 + * + * @defgroup nfc_ble_oob_advdata Advertising and Scan Response Data Encoder for NFC OOB pairing + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Function for encoding data in the Advertising and Scan Response Data format, which + * can be used to create payload of NFC message intended for initiating the Out-of-Band + * pairing. + */ + +#ifndef NFC_BLE_OOB_ADVDATA_H__ +#define NFC_BLE_OOB_ADVDATA_H__ + +#include <stdint.h> +#include "ble_advdata.h" +#include "app_util.h" +#include "sdk_errors.h" + + +/**@brief Function for encoding data in the Advertising and Scan Response data format, which + * is used for NFC OOB pairing. + * + * + * @details This function encodes data into the Advertising and Scan Response data format (AD structures). + * Encoding is based on the selections in the supplied structures. This function uses + * @ref ble_advdata_encode to encode regular data and adds additional AD Structures which are specific + * for NFC OOB pairing: Security Manager TK Value, LESC OOB values, OOB Flags, and LE Role. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer. + * \c out: Length of encoded data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata. + * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the + * provided buffer or some encoded AD structure is too long and its + * length cannot be encoded with one octet. + */ +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len); + +/**@brief Function for encoding payload field of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_tk_payload_data Pointer to the buffer where TK payload data will be stored. + * + */ +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data); + +#endif // NFC_BLE_OOB_ADVDATA_H__ + +/** @} */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c new file mode 100644 index 0000000..d356d61 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c @@ -0,0 +1,641 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_BLE_PAIR_LIB) + +#include "nfc_ble_pair_lib.h" +#include "sdk_macros.h" +#include "app_error.h" +#include "nrf_drv_rng.h" +#include "nfc_t2t_lib.h" +#include "nfc_ble_pair_msg.h" +#include "ecc.h" +#include "nrf_sdh_ble.h" + +#define NRF_LOG_MODULE_NAME nfc_ble_pair +#if NFC_BLE_PAIR_LIB_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_BLE_PAIR_LIB_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_BLE_PAIR_LIB_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR NFC_BLE_PAIR_LIB_DEBUG_COLOR +#else // NFC_BLE_PAIR_LIB_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_BLE_PAIR_LIB_LOG_ENABLED +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +// Verify bonding and keys distribution settings. +#if ((BLE_NFC_SEC_PARAM_BOND) && \ + !(BLE_NFC_SEC_PARAM_KDIST_OWN_ENC) && \ + !(BLE_NFC_SEC_PARAM_KDIST_OWN_ID) && \ + !(BLE_NFC_SEC_PARAM_KDIST_PEER_ENC) && \ + !(BLE_NFC_SEC_PARAM_KDIST_PEER_ID)) + #error "At least one of the BLE_NFC_SEC_PARAM_KDIST flags must be set to 1 when bonding is enabled." +#endif + +// Macro for verifying if the pairing mode argument is valid +#define VERIFY_PAIRING_MODE(arg) \ + if ((arg) >= NFC_PAIRING_MODE_CNT) \ + { \ + return NRF_ERROR_INVALID_PARAM; \ + } + +#define BLE_GAP_LESC_P256_SK_LEN 32 /**< GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key Length. */ +#define TK_MAX_NUM 1 /**< Maximal number of TK locations in NDEF message buffer. */ +#define NDEF_MSG_BUFF_SIZE 256 /**< Size of buffer for the NDEF pairing message. */ + +#define BLE_NFC_SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ +#define BLE_NFC_SEC_PARAM_IO_CAPS BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ + +typedef struct +{ + uint8_t sk[BLE_GAP_LESC_P256_SK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key. */ +} ble_gap_lesc_p256_sk_t; + +static ble_advertising_t * m_p_advertising = NULL; /**< Pointer to the advertising module instance. */ + +static uint8_t m_ndef_msg_buf[NDEF_MSG_BUFF_SIZE]; /**< NFC tag NDEF message buffer. */ +static ble_advdata_tk_value_t m_oob_auth_key; /**< Temporary Key buffer used in OOB legacy pairing mode. */ +static uint8_t * m_tk_group[TK_MAX_NUM]; /**< Locations of TK in NDEF message. */ +static nfc_pairing_mode_t m_pairing_mode; /**< Current pairing mode. */ +static ble_gap_lesc_oob_data_t m_ble_lesc_oob_data; /**< LESC OOB data used in LESC OOB pairing mode. */ +static ble_gap_sec_params_t m_sec_param; /**< Current Peer Manager secure parameters configuration. */ + +static uint8_t m_connections = 0; /**< Number of active connections. */ + +__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_pk; /**< LESC ECC Public Key. */ +__ALIGN(4) static ble_gap_lesc_p256_sk_t m_lesc_sk; /**< LESC ECC Secret Key. */ +__ALIGN(4) static ble_gap_lesc_dhkey_t m_lesc_dhkey; /**< LESC ECC DH Key. */ +__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_peer_pk; /**< LESC Peer ECC Public Key. */ + + +static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context); + +NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO, ble_evt_handler, NULL); + +/** + * @brief Generates random values to a given buffer + * + * @param[out] p_buff Buffer for random values + * @param[in] size Number of bytes to generate + * + * @returns Number of generated bytes + */ +static uint8_t random_vector_generate(uint8_t * p_buff, uint8_t size) +{ + uint8_t available; + ret_code_t err_code = NRF_SUCCESS; + + nrf_drv_rng_bytes_available(&available); + + uint8_t length = (size < available) ? size : available; + err_code = nrf_drv_rng_rand(p_buff, length); + APP_ERROR_CHECK(err_code); + return length; +} + +/** + * @brief Prints generated key to the log console + * + * @param[in] lenght TK value length + */ +static void random_vector_log(uint8_t length) +{ + NRF_LOG_INFO("TK Random Value:"); + for (uint32_t i = 0; i < length; i++) + { + NRF_LOG_RAW_INFO(" %02X",(int)m_oob_auth_key.tk[i]); + } + NRF_LOG_RAW_INFO("\r\n"); +} + +/** + * @brief Function for handling NFC events. + * + * @details Starts advertising and generates new OOB keys on the NFC_T2T_EVENT_FIELD_ON event. + * + * @param[in] p_context Context for callback execution, not used in this callback implementation. + * @param[in] event Event generated by hal NFC lib. + * @param[in] p_data Received/transmitted data or NULL, not used in this callback implementation. + * @param[in] data_length Size of the received/transmitted packet, not used in this callback implementation. + */ +static void nfc_callback(void * p_context, + nfc_t2t_event_t event, + uint8_t const * p_data, + size_t data_length) +{ + UNUSED_PARAMETER(p_context); + UNUSED_PARAMETER(p_data); + UNUSED_PARAMETER(data_length); + + ret_code_t err_code = NRF_SUCCESS; + nfc_pairing_mode_t pairing_mode; + + switch (event) + { + case NFC_T2T_EVENT_FIELD_ON: + NRF_LOG_DEBUG("NFC_EVENT_FIELD_ON"); + + pairing_mode = nfc_ble_pair_mode_get(); + + if ((pairing_mode == NFC_PAIRING_MODE_OOB) || + (pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB)) + { + // Generate Authentication OOB Key and update NDEF message content. + uint8_t length = random_vector_generate(m_oob_auth_key.tk, BLE_GAP_SEC_KEY_LEN); + random_vector_log(length); + err_code = nfc_tk_group_modifier_update(&m_oob_auth_key); + APP_ERROR_CHECK(err_code); + } + + // Start advertising when NFC field is sensed and there is a place for another connection. + if (m_connections < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT) + { + err_code = ble_advertising_start(m_p_advertising, BLE_ADV_MODE_FAST); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + } + + break; + + case NFC_T2T_EVENT_FIELD_OFF: + NRF_LOG_DEBUG("NFC_EVENT_FIELD_OFF"); + break; + + default: + break; + } +} + +/** + * @brief Function for setting the Peer Manager secure mode used in device pairing. + * + * @param[in] mode NFC pairing mode, this is the value of @ref nfc_pairing_mode_t enum + * + * @retval NRF_SUCCESS If new secure mode has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +static ret_code_t pm_secure_mode_set(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid. + VERIFY_PAIRING_MODE(mode); + + memset(&m_sec_param, 0x00, sizeof(m_sec_param)); + + // Pairing mode specific security parameters. + switch (mode) + { + case NFC_PAIRING_MODE_JUST_WORKS: + // Disable pairing with OOB data. + m_sec_param.mitm = 0; + m_sec_param.oob = 0; + m_sec_param.lesc = 0; + break; + + case NFC_PAIRING_MODE_OOB: + // Enable legacy pairing with OOB data - TK value. + m_sec_param.mitm = 1; + m_sec_param.oob = 1; + m_sec_param.lesc = 0; + break; + + case NFC_PAIRING_MODE_LESC_OOB: + case NFC_PAIRING_MODE_LESC_JUST_WORKS: + // Enable LESC pairing - OOB and MITM flags are cleared because it is the central device + // who decides if the connection will be authorized with LESC OOB data. + m_sec_param.mitm = 0; + m_sec_param.oob = 0; + m_sec_param.lesc = 1; + break; + + case NFC_PAIRING_MODE_GENERIC_OOB: + // MITM, OOB and LESC flags are changing dynamically depending on central device pairing flags. + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + // Common security parameters to be used for all security procedures. + m_sec_param.min_key_size = BLE_NFC_SEC_PARAM_MIN_KEY_SIZE; + m_sec_param.max_key_size = BLE_NFC_SEC_PARAM_MAX_KEY_SIZE; + m_sec_param.keypress = BLE_NFC_SEC_PARAM_KEYPRESS; + m_sec_param.io_caps = BLE_NFC_SEC_PARAM_IO_CAPS; + m_sec_param.bond = BLE_NFC_SEC_PARAM_BOND; + +#if (BLE_NFC_SEC_PARAM_BOND) + // If bonding is enabled, set key distribution flags. + m_sec_param.kdist_own.enc = BLE_NFC_SEC_PARAM_KDIST_OWN_ENC; + m_sec_param.kdist_own.id = BLE_NFC_SEC_PARAM_KDIST_OWN_ID; + m_sec_param.kdist_peer.enc = BLE_NFC_SEC_PARAM_KDIST_PEER_ENC; + m_sec_param.kdist_peer.id = BLE_NFC_SEC_PARAM_KDIST_PEER_ID; +#else + // If bonding is not enabled, no keys can be distributed. + m_sec_param.kdist_own.enc = 0; + m_sec_param.kdist_own.id = 0; + m_sec_param.kdist_peer.enc = 0; + m_sec_param.kdist_peer.id = 0; +#endif + + // Update Peer Manager security parameter settings. + err_code = pm_sec_params_set(&m_sec_param); + + return err_code; +} + + + /**@brief Function for preparing the BLE pairing data for the NFC tag. + * + * @details This function does not stop and start the NFC tag data emulation. + * + * @param[in] mode Pairing mode for which the tag data will be prepared. + * + * @retval NRF_SUCCESS If new tag pairing data has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_data_set(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + // Provide information about available buffer size to encoding function. + uint32_t ndef_msg_len = sizeof(m_ndef_msg_buf); + + switch (mode) + { + case NFC_PAIRING_MODE_OOB: + // Encode NDEF message with Secure Simple Pairing OOB optional data - TK value. + err_code = nfc_ble_pair_msg_updatable_tk_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + &m_oob_auth_key, + NULL, + m_ndef_msg_buf, + &ndef_msg_len, + m_tk_group, + TK_MAX_NUM); + break; + + case NFC_PAIRING_MODE_JUST_WORKS: + // Encode NDEF message with Secure Simple Pairing OOB data. + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + NULL, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + case NFC_PAIRING_MODE_LESC_OOB: + // Generate LESC OOB data + err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID, + &m_lesc_pk, + &m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + + // Encode NDEF message with BLE LESC OOB pairing data - LESC random and confirmation values. + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + &m_ble_lesc_oob_data, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + case NFC_PAIRING_MODE_LESC_JUST_WORKS: + err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + NULL, + NULL, + m_ndef_msg_buf, + &ndef_msg_len); + break; + + case NFC_PAIRING_MODE_GENERIC_OOB: + // Generate LESC OOB data + err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID, + &m_lesc_pk, + &m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + + // Encode NDEF message with Secure Simple Pairing OOB data - TK value and LESC Random and Confirmation Keys. + err_code = nfc_ble_pair_msg_updatable_tk_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, + &m_oob_auth_key, + &m_ble_lesc_oob_data, + m_ndef_msg_buf, + &ndef_msg_len, + m_tk_group, + TK_MAX_NUM); + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + VERIFY_SUCCESS(err_code); + + // Update NFC tag data + err_code = nfc_t2t_payload_set(m_ndef_msg_buf, ndef_msg_len); + + return err_code; +} + +ret_code_t nfc_ble_pair_init(ble_advertising_t * const p_advertising, nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + // Check if pointer to the advertising module instance is not NULL + VERIFY_PARAM_NOT_NULL(p_advertising); + + m_p_advertising = p_advertising; + m_pairing_mode = mode; + + // Initialize RNG peripheral for authentication OOB data generation + err_code = nrf_drv_rng_init(NULL); + if (err_code != NRF_ERROR_INVALID_STATE) + { + VERIFY_SUCCESS(err_code); + } + + // Initialize encryption module with random number generator use + ecc_init(true); + + // Start NFC + err_code = nfc_t2t_setup(nfc_callback, NULL); + VERIFY_SUCCESS(err_code); + + // Set Peer Manager pairing mode + err_code = pm_secure_mode_set(mode); + VERIFY_SUCCESS(err_code); + + if ((mode == NFC_PAIRING_MODE_LESC_OOB) || + (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) || + (mode == NFC_PAIRING_MODE_GENERIC_OOB)) + { + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + } + + // Set proper NFC data according to the pairing mode + err_code = nfc_ble_pair_data_set(mode); + VERIFY_SUCCESS(err_code); + + // Turn on tag emulation + err_code = nfc_t2t_emulation_start(); + + return err_code; +} + +ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Check if pairing mode is valid + VERIFY_PAIRING_MODE(mode); + + if (mode != m_pairing_mode) + { + m_pairing_mode = mode; + + if ((mode == NFC_PAIRING_MODE_LESC_OOB) || + (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) || + (mode == NFC_PAIRING_MODE_GENERIC_OOB)) + { + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + } + + // Update Peer Manager settings according to the new pairing mode + err_code = pm_secure_mode_set(mode); + VERIFY_SUCCESS(err_code); + + // NFC tag emulation must be turned off during changes in payload + err_code = nfc_t2t_emulation_stop(); + VERIFY_SUCCESS(err_code); + + // Update NFC tag data + err_code = nfc_ble_pair_data_set(mode); + VERIFY_SUCCESS(err_code); + + // Turn on tag emulation after changes + err_code = nfc_t2t_emulation_start(); + VERIFY_SUCCESS(err_code); + } + + return NRF_SUCCESS; +} + +nfc_pairing_mode_t nfc_ble_pair_mode_get(void) +{ + return m_pairing_mode; +} + +/** + * @brief Generates new key pair for LESC pairing. + * + * @details If device is in the @ref NFC_PAIRING_MODE_LESC_OOB mode or in + * the @ref NFC_PAIRING_MODE_GENERIC_OOB mode, NFC Connection Handover + * message is also updated with newly generated LESC OOB data. + * + * @retval NRF_SUCCESS If new tag pairing data has been set correctly. + * @retval Other Other error codes might be returned depending on used modules. + */ +static ret_code_t generate_lesc_keys(void) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Generate new LESC keys + err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk); + VERIFY_SUCCESS(err_code); + + // Update Peer Manager with new LESC Public Key + err_code = pm_lesc_public_key_set(&m_lesc_pk); + VERIFY_SUCCESS(err_code); + + if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) || + (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB)) + { + // Generate LESC OOB data. + err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID, + &m_lesc_pk, + &m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + + // Update NDEF message with new LESC OOB data. + err_code = nfc_lesc_data_update(&m_ble_lesc_oob_data); + VERIFY_SUCCESS(err_code); + } + + return NRF_SUCCESS; +} + +/** + * @brief Function for handling BLE events. + * + * @param[in] p_ble_evt Event received from the BLE stack. + * @param[in] p_context Context. + */ +static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) +{ + ret_code_t err_code = NRF_SUCCESS; + + switch (p_ble_evt->header.evt_id) + { + // Upon authorization key request, reply with Temporary Key that was read from the NFC tag + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + NRF_LOG_DEBUG("BLE_GAP_EVT_AUTH_KEY_REQUEST"); + + err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_AUTH_KEY_TYPE_OOB, + m_oob_auth_key.tk); + APP_ERROR_CHECK(err_code); + break; + + // Upon LESC Diffie_Hellman key request, reply with key computed from device secret key and peer public key + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + NRF_LOG_DEBUG("BLE_GAP_EVT_LESC_DHKEY_REQUEST"); + + // If LESC OOB pairing is on, perform authentication with OOB data + if (p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.oobd_req) + { + err_code = sd_ble_gap_lesc_oob_data_set(p_ble_evt->evt.gap_evt.conn_handle, + &m_ble_lesc_oob_data, + NULL); + APP_ERROR_CHECK(err_code); + } + + // Buffer peer Public Key because ECC module arguments must be word aligned + memcpy(&m_lesc_peer_pk.pk[0], + &p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer->pk[0], + BLE_GAP_LESC_P256_PK_LEN); + + // Compute D-H key + err_code = ecc_p256_shared_secret_compute(&m_lesc_sk.sk[0], + &m_lesc_peer_pk.pk[0], + &m_lesc_dhkey.key[0]); + APP_ERROR_CHECK(err_code); + + // Reply with obtained result + err_code = sd_ble_gap_lesc_dhkey_reply(p_ble_evt->evt.gap_evt.conn_handle, + &m_lesc_dhkey); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GAP_EVT_CONNECTED: + m_connections++; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_connections--; + // Intentional fallthrough. + + case BLE_GAP_EVT_AUTH_STATUS: + // Generate new LESC key pair and OOB data + if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) || + (m_pairing_mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) || + (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB)) + { + err_code = generate_lesc_keys(); + APP_ERROR_CHECK(err_code); + } + break; + + default: + break; + } +} + +ret_code_t nfc_ble_pair_on_pm_params_req(pm_evt_t const * p_evt) +{ + ret_code_t err_code = NRF_SUCCESS; + + NRF_LOG_DEBUG("PM_EVT_CONN_SEC_PARAMS_REQ"); + + // Dynamic security parameters changes are needed only + // by NFC_PAIRING_MODE_GENERIC_OOB pairing mode. + if (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB) + { + // Check if pointer to the Peer Manager event is not NULL. + VERIFY_PARAM_NOT_NULL(p_evt); + + // Set up proper MITM, OOB and LESC flags depending on peer LESC flag + // to support either Legacy OOB or LESC OOB pairing mode. + if (p_evt->params.conn_sec_params_req.p_peer_params->lesc) + { + NRF_LOG_DEBUG("LESC OOB mode flags set."); + + m_sec_param.mitm = 0; + m_sec_param.oob = 0; + m_sec_param.lesc = 1; + } + else + { + NRF_LOG_DEBUG("Legacy OOB mode flags set."); + + m_sec_param.mitm = 1; + m_sec_param.oob = 1; + m_sec_param.lesc = 0; + } + + // Reply with new security parameters to the Peer Manager. + err_code = pm_conn_sec_params_reply(p_evt->conn_handle, + &m_sec_param, + p_evt->params.conn_sec_params_req.p_context); + } + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_BLE_PAIR_LIB) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h new file mode 100644 index 0000000..4809cf2 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h @@ -0,0 +1,137 @@ +/** + * 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. + * + */ +#ifndef NFC_BLE_PAIR_LIB_H__ +#define NFC_BLE_PAIR_LIB_H__ + +#include <stdbool.h> +#include "sdk_errors.h" +#include "ble.h" +#include "ble_advertising.h" +#include "peer_manager.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @addtogroup nfc_api + * + * @defgroup nfc_ble_pair_lib NFC BLE Pairing Library + * @ingroup nfc_api + * @brief @tagAPI52 High-level library for BLE Connection Handover pairing using NFC. + * @{ + */ + +/** + * @brief NFC pairing types. + */ +typedef enum +{ + NFC_PAIRING_MODE_JUST_WORKS, /**< Legacy Just Works pairing without a security key. */ + NFC_PAIRING_MODE_OOB, /**< Legacy OOB pairing with a Temporary Key shared through NFC tag data. */ + NFC_PAIRING_MODE_LESC_JUST_WORKS, /**< LESC pairing without authentication data. */ + NFC_PAIRING_MODE_LESC_OOB, /**< LESC pairing with OOB authentication data. */ + NFC_PAIRING_MODE_GENERIC_OOB, /**< OOB pairing with fallback from LESC to Legacy mode. */ + NFC_PAIRING_MODE_CNT /**< Number of available pairing modes. */ +} nfc_pairing_mode_t; + +/** + * @brief Funtion for initializing NFC tag data and turning on tag emulation. + * + * @warning It is assumed that Peer Manager has already been initialized before calling this function. + * It is also assumed that BLE advertising has already been initialized and it is configured + * to run in the BLE_ADV_MODE_FAST mode. + * + * @param[in] mode Pairing mode, this is the value of the @ref nfc_pairing_mode_t enum. + * @param[in] p_advertising Pointer to the advertising module instance. + * + * @retval NRF_SUCCESS If NFC has been initialized properly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval NRF_ERROR_NULL If pointer to the advertising module instance is NULL. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_init(ble_advertising_t * const p_advertising, nfc_pairing_mode_t mode); + +/** + * @brief Function for setting pairing data and BLE security mode. + * + * @param[in] mode New pairing mode, this is the value of the @ref nfc_pairing_mode_t enum. + * + * @retval NRF_SUCCESS If new pairing mode has been set correctly. + * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid. + * @retval Other Other error codes might be returned depending on used modules. + */ +ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode); + +/** + * @brief Function for obtaining the current pairing mode. + * + * @return Current pairing mode. + */ +nfc_pairing_mode_t nfc_ble_pair_mode_get(void); + +/** + * @brief Function for replying to @ref PM_EVT_CONN_SEC_PARAMS_REQ. + * + * @details This function is used to allow dynamic changes in the Peer Manager + * security parameters depending on security parameters + * obtained from the peer. This is essential for dynamic switching + * between Legacy OOB and LESC OOB pairing modes when pairing + * library works in @ref NFC_PAIRING_MODE_GENERIC_OOB mode. + * + * @note This function invokes the @ref pm_conn_sec_params_reply function. + * + * @param[in] p_evt Pointer to the Peer Manager event struct with + * information about peer security parameters. + * + * @retval NRF_SUCCESS If proper reply has been sent or library does not need to reply. + * @retval NRF_ERROR_NULL If pointer to the Peer Manager event is NULL. + * @retval Other Other error codes might be returned by the @ref pm_conn_sec_params_reply function. + */ +ret_code_t nfc_ble_pair_on_pm_params_req(pm_evt_t const * p_evt); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_LIB_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c new file mode 100644 index 0000000..88cb6a9 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c @@ -0,0 +1,411 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_BLE_PAIR_MSG) + +#include "nfc_ble_pair_msg.h" +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nfc_le_oob_rec.h" +#include "nfc_ep_oob_rec.h" +#include "nfc_ndef_msg.h" +#include "sdk_macros.h" + +/** + * @brief Descriptor of TK value locations in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t ** pp_tk_group; /**< Pointer to array of pointer with TK locations in CH NDEF message. */ + uint8_t tk_num; /**< Number of valid TK locations. */ + uint8_t tk_max_num; /**< Maximal number of possible TK locations. */ +} nfc_ble_tk_group_t; + +/** + * @brief Descriptor of LESC OOB data in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t * confirm; /**< Pointer to the LESC OOB confirmation value in the CH NDEF message. */ + uint8_t * random; /**< Pointer to the LESC OOB random value in the CH NDEF message. */ +} nfc_ble_lesc_data_pos_t; + +static nfc_ble_lesc_data_pos_t m_lesc_pos = {NULL, NULL}; /**< Descriptor used to update LESC keys in the NDEF Message */ +static nfc_ble_tk_group_t m_tk_group; /**< Descriptor used to find TK locations in the NDEF Message which require update. */ +static bool m_tk_modifier_on = false; /**< Flag indicating that TK modifier feature is on. */ + +/* Default value for Security Manager Out Of Band Flags field in BLE AD structure */ +/* which is used for EP OOB Record payload */ +static const uint8_t sec_mgr_oob_flags = + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR << AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS) | + (AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM << AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS); + +/**@brief Function for configuring TK group modifier feature. + * + * @details This function configures the structure which is responsible for tracking TK locations. + * These locations can be afterwards easily accessed with @ref nfc_tk_group_modifier_update + * and modified. + * + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + */ +__STATIC_INLINE void nfc_tk_group_modifier_config(uint8_t ** pp_tk_group, uint8_t max_group_size) +{ + m_tk_group.pp_tk_group = pp_tk_group; + m_tk_group.tk_num = 0; + m_tk_group.tk_max_num = max_group_size; +} + +/** @brief Function for creating an AD structure with common configuration for EP and LE OOB records. + * + * This function creates an AD structure and initializes its fields with default content. Only + * fields that are common for both EP and LE OOB records are filled. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_adv_data Pointer to BLE AD structure with common configuration for EP + * and LE OOB records. + */ +static void common_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_adv_data) +{ + memset((uint8_t *) p_adv_data, 0, sizeof(ble_advdata_t)); + + /* Set common configuration of AD structure for both Bluetooth EP and LE record */ + p_adv_data->include_appearance = true; + p_adv_data->name_type = BLE_ADVDATA_FULL_NAME; + p_adv_data->p_tk_value = NULL; + if (p_tk_value != NULL) + { + p_adv_data->p_tk_value = p_tk_value; + } + + p_adv_data->p_lesc_data = p_lesc_data; +} + +/** @brief Function for creating an AD structure with default configuration for an LE OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * LE OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_le_adv_data Pointer to BLE AD structure with default configuration + * for LE OOB record. + */ +static void le_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_le_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_le_adv_data); + + /* LE specific configuration */ + p_le_adv_data->include_ble_device_addr = true; + p_le_adv_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH; + p_le_adv_data->flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; +} + +/** @brief Function for creating an AD structure with default configuration for an EP OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * EP OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_ep_adv_data Pointer to BLE AD structure with default configuration + * for EP OOB record. + */ +static void ep_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_ep_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_ep_adv_data); + + /* EP specific configuration */ + p_ep_adv_data->p_sec_mgr_oob_flags = (uint8_t *) &sec_mgr_oob_flags; +} + +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_le_oob_msg, 1); + + /* Create NFC NDEF LE OOB Record description without record ID field */ + NFC_NDEF_LE_OOB_RECORD_DESC_DEF(nfc_le_oob_rec, 0, p_le_advdata); + + /* Add LE OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_le_oob_msg), + &NFC_NDEF_LE_OOB_RECORD_DESC(nfc_le_oob_rec)); + VERIFY_SUCCESS(err_code); + VERIFY_PARAM_NOT_NULL(p_le_advdata); + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_le_oob_msg), + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_ep_oob_msg, 1); + + /* Create NFC NDEF EP OOB Record description without record ID field */ + NFC_NDEF_EP_OOB_RECORD_DESC_DEF(nfc_ep_oob_rec, 0, p_ep_advdata); + + /* Add EP OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_ep_oob_msg), + &NFC_NDEF_EP_OOB_RECORD_DESC(nfc_ep_oob_rec)); + VERIFY_SUCCESS(err_code); + VERIFY_PARAM_NOT_NULL(p_ep_advdata); + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_ep_oob_msg), + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + + // Carrier reference buffers for ac records. + uint8_t carrier_le_reference = '0'; + uint8_t carrier_ep_reference = '1'; + + // Create ac records for both message types. + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_le, NFC_AC_CPS_ACTIVE, 1, &carrier_le_reference, 1); + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_ep, NFC_AC_CPS_ACTIVE, 1, &carrier_ep_reference, 1); + + // Create a Hs record and assign existing ac records to it. + NFC_NDEF_HS_RECORD_DESC_DEF(hs_rec, 1, 3, 2); + err_code = nfc_hs_rec_local_record_add(&NFC_NDEF_HS_RECORD_DESC(hs_rec), + &NFC_NDEF_AC_RECORD_DESC(ac_rec_le)); + VERIFY_SUCCESS(err_code); + err_code = nfc_hs_rec_local_record_add(&NFC_NDEF_HS_RECORD_DESC(hs_rec), + &NFC_NDEF_AC_RECORD_DESC(ac_rec_ep)); + VERIFY_SUCCESS(err_code); + + // Create LE and EP records with different record IDs. + NFC_NDEF_LE_OOB_RECORD_DESC_DEF(nfc_le_oob_rec, carrier_le_reference, p_le_advdata); + NFC_NDEF_EP_OOB_RECORD_DESC_DEF(nfc_ep_oob_rec, carrier_ep_reference, p_ep_advdata); + + // Create full NDEF Handover Select message for Connection Handover and assign Hs, + // LE and EP records to it. + NFC_NDEF_MSG_DEF(nfc_hs_full_msg, 3); + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg), + &NFC_NDEF_HS_RECORD_DESC(hs_rec)); + VERIFY_SUCCESS(err_code); + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg), + &NFC_NDEF_LE_OOB_RECORD_DESC(nfc_le_oob_rec)); + VERIFY_SUCCESS(err_code); + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg), + &NFC_NDEF_EP_OOB_RECORD_DESC(nfc_ep_oob_rec)); + VERIFY_SUCCESS(err_code); + + VERIFY_PARAM_NOT_NULL(p_le_advdata); + VERIFY_PARAM_NOT_NULL(p_ep_advdata); + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_hs_full_msg), + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len) +{ + ble_advdata_t le_adv_data; + ble_advdata_t ep_adv_data; + ret_code_t err_code = NRF_SUCCESS; + + switch (nfc_ble_pair_type) + { + + case NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + err_code = nfc_ble_simplified_le_oob_msg_encode(&le_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT: + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_simplified_ep_oob_msg_encode(&ep_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_FULL: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_full_handover_select_msg_encode(&le_adv_data, + &ep_adv_data, + p_buf, + p_len); + break; + + } + + return err_code; +} + +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size) +{ + ret_code_t err_code = NRF_SUCCESS; + + m_tk_modifier_on = true; + nfc_tk_group_modifier_config(pp_tk_group, max_group_size); + err_code = nfc_ble_pair_default_msg_encode(nfc_ble_pair_type, p_tk_value, + p_lesc_data, p_buf, p_len); + m_tk_modifier_on = false; + + return err_code; +} + +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value) +{ + VERIFY_PARAM_NOT_NULL(m_tk_group.pp_tk_group); + for (uint8_t tk_index = 0; tk_index < m_tk_group.tk_num; ++tk_index) + { + uint8_t * p_tk_payload_data = m_tk_group.pp_tk_group[tk_index]; + nfc_tk_value_payload_encode(p_tk_value, p_tk_payload_data); + } + return NRF_SUCCESS; +} + +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location) +{ + // Feature was disabled. + if (m_tk_group.pp_tk_group == NULL) + { + return NRF_SUCCESS; + } + + if (m_tk_group.tk_num < m_tk_group.tk_max_num) + { + m_tk_group.pp_tk_group[m_tk_group.tk_num++] = p_tk_location; + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NO_MEM; + } +} + +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random) +{ + if ((p_confirm != NULL) && (p_random != NULL)) + { + m_lesc_pos.confirm = p_confirm; + m_lesc_pos.random = p_random; + + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NULL; + } +} + +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * p_ble_lesc_oob_data) +{ + if (p_ble_lesc_oob_data != NULL) + { + if ((m_lesc_pos.confirm != NULL) && (m_lesc_pos.random != NULL)) + { + memcpy(m_lesc_pos.confirm, p_ble_lesc_oob_data->c, AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + memcpy(m_lesc_pos.random, p_ble_lesc_oob_data->r, AD_TYPE_RANDOM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_STATE; + } + else + { + return NRF_ERROR_NULL; + } +} + +#endif // NRF_MODULE_ENABLED(NFC_BLE_PAIR_MSG) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h new file mode 100644 index 0000000..ab7ce18 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h @@ -0,0 +1,279 @@ +/** + * 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 NFC_BLE_PAIR_MSG_H__ +#define NFC_BLE_PAIR_MSG_H__ + +/**@file + * + * @defgroup nfc_modules NDEF message modules + * @ingroup nfc_api + * @brief Implementation of NDEF messages. + * + * @defgroup nfc_ndef_messages Predefined NDEF messages + * @ingroup nfc_modules + * @brief Predefined NDEF messages for standard use. + * + * @defgroup nfc_ble_pair_msg BLE pairing messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages used for BLE pairing. + * + */ + +#include <stdint.h> +#include "ble_advdata.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Types of BLE pairing message. + * + * Use one of these values to choose the type of NDEF BLE pairing message. + */ +typedef enum +{ + NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, ///< Simplified LE OOB message. + NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT, ///< Simplified EP OOB message. + NFC_BLE_PAIR_MSG_FULL ///< BLE Handover Select Message. +} nfc_ble_pair_type_t; + +/** @brief Function for encoding simplified LE OOB messages. + * + * This function encodes a simplified LE OOB message into a buffer. The payload of the LE OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.2, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding simplified EP OOB messages. + * + * This function encodes a simplified EP OOB message into a buffer. The payload of the EP OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.1, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding BLE Handover Select Messages. + * + * This function encodes a BLE Handover Select Message into a buffer. The payload of the LE OOB record + * and the EP OOB record inside the message can be configured via the advertising data structures. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.1.1 + * and 4.1.2 (combined), and according to "Supplement to the Bluetooth Core Specification" (Version 5, + * adoption date: Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures. + * + * This function encodes a BLE pairing message into a buffer. The message can be encoded as + * one of the three message types (using @ref nfc_ble_simplified_le_oob_msg_encode, + * @ref nfc_ble_simplified_ep_oob_msg_encode, or @ref nfc_ble_full_handover_select_msg_encode), + * according to the @p nfc_ble_pair_type parameter. LE and EP OOB records use the default + * advertising data structure configuration. Only one field ('Security Manager TK') in the BLE + * advertising data can be configured for both records by specifying the @p p_tk_value parameter. + * + * For LE OOB records, the default BLE advertising data structure configuration fills the required + * fields 'LE Bluetooth Device Address' and 'LE Role' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * For EP OOB records, the default BLE advertising data structure configuration fills the required + * field 'Security Manager Out Of Band Flags' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB fields are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures and with TK modifier feature. + * + * This function is very similar to the @ref nfc_ble_pair_default_msg_encode function, but + * additionaly enables tracking of TK locations which were encoded in the Connection Handover + * NDEF message. After using this function, you can update the TK value in NDEF by calling + * @ref nfc_tk_group_modifier_update. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB values are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size); + +/**@brief Function for updating the Connection Handover NDEF message with new TK value. + * + * @details This function updates NDEF message with new TK value. This update is applied to all of + * TK locations in the Connection Handover NDEF message. This function can only be used + * after calling @ref nfc_ble_pair_msg_updatable_tk_encode, which is used to encode + * Connection Handover NDEF message. + * + * @param[in] p_tk_value Pointer to the new TK value. The NDEF message will be updated with this + * value. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to TK locations was NULL. + */ +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value); + +/**@brief Function for adding new location of TK value to the location description structure. + * + * @param[in] p_tk_location New location of TK value in the Connection Handover NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful or if buffer used for holding TK + * locations is NULL. + * @retval NRF_ERROR_NO_MEM If there is no place in the buffer for the new TK value location. + */ +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location); + +/**@brief Function for updating the Connection Handover NDEF message with a new LESC OOB values. + * + * @details Updates LESC Confirmation and Random Values based on its locations set by the @ref nfc_lesc_pos_set function. + * + * @param[in] p_ble_lesc_oob_data Pointer to the new LESC OOB data. The NDEF message will be updated with this data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to the new LESC OOB data is NULL. + * @retval NRF_ERROR_INVALID_STATE If pointer to the LESC OOB data location in NDEF message is NULL. + */ +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * p_ble_lesc_oob_data); + +/**@brief Function for storing pointers to the LESC OOB data inside NDEF message. + * + * @details It allows LESC OOB data update without regenerating entire CH NDEF message. + * + * @param[in] p_confirm Pointer to the LESC Confirmation Value position in the NDEF message. + * @param[in] p_random Pointer to the LESC Random Value position in the NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If either of pointers is set to NULL. + */ +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_MSG_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c new file mode 100644 index 0000000..31bf824 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c @@ -0,0 +1,53 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_CH_COMMON) +#include "nfc_ble_pair_common.h" + +#include <stdint.h> + +/* Record Payload Type for Bluetooth Carrier Configuration LE record */ +const uint8_t le_oob_rec_type_field[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'l', 'e', '.', 'o', 'o', 'b' +}; + +#endif // NRF_MODULE_ENABLED(NFC_CH_COMMON) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h new file mode 100644 index 0000000..e9e26e7 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h @@ -0,0 +1,106 @@ +/** + * 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. + * + */ +#ifndef NFC_BLE_PAIR_COMMON_H__ +#define NFC_BLE_PAIR_COMMON_H__ + +#include <stdint.h> +#include "ble_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * @defgroup nfc_ble_pair_common Common data for Connection Handover and Connection Handover Parser modules + * @{ + * @ingroup nfc_ble_pair_msg + */ + +#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Role AD type. */ +#define AD_TYPE_LE_ROLE_SIZE (AD_DATA_OFFSET + \ + AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Role AD type. */ +#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_TK_VALUE_SIZE (AD_DATA_OFFSET + \ + AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */ +#define AD_TYPE_OOB_FLAGS_SIZE (AD_DATA_OFFSET + \ + AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */ + +#define AD_TYPE_CONFIRM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Confirmation value. */ +#define AD_TYPE_CONFIRM_VALUE_SIZE (AD_DATA_OFFSET + \ + AD_TYPE_CONFIRM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Confirmation value AD type. */ +#define AD_TYPE_RANDOM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Random value. */ +#define AD_TYPE_RANDOM_VALUE_SIZE (AD_DATA_OFFSET + \ + AD_TYPE_RANDOM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Random value AD type. */ +#define AD_TYPE_LESC_SIZE (AD_TYPE_RANDOM_VALUE_SIZE + \ + AD_TYPE_CONFIRM_VALUE_SIZE) /**< Total size (in octets) of the LESC OOB AD data fields in NDEF message. */ + +#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */ + +/**@brief Payload field values of LE Role BLE GAP AD Type. Corresponds with @ref ble_advdata_le_role_t enum. */ +typedef enum +{ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH = 0, /**< Only Peripheral Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL, /**< Only Central Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */ +} nfc_ble_advdata_le_role_encoded_t; + +/** + * @brief External reference to the type field of the Bluetooth LE Carrier Configuration NDEF record, defined + * in the file @c nfc_ble_pair_common.c + */ +extern const uint8_t le_oob_rec_type_field[32]; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_COMMON_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c new file mode 100644 index 0000000..12ab9f6 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c @@ -0,0 +1,188 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_EP_OOB_REC) + +#include "nfc_ep_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "app_util.h" + +/* NFC OOB EP definitions */ +#define NFC_EP_OOB_REC_GAP_ADDR_LEN BLE_GAP_ADDR_LEN +#define NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE 2UL +#define NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN (NFC_EP_OOB_REC_GAP_ADDR_LEN + \ + NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE) + +/* Record Payload Type for Bluetooth Carrier Configuration EP record */ +const uint8_t ndef_ep_oob_record_type[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'e', 'p', '.', 'o', 'o', 'b' +}; + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration EP record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields must not be included. Security Manager OOB Flags structure is required. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_ep_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((true == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT != p_ble_advdata->le_role) || + (NULL == p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + +/** + * @brief Function for encoding device address to Bluetooth Carrier Configuration EP record. + * + * This fuction is used to encode device address to Bluetooth Carrier Configuration EP record. + * + * @param[in] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in] max_len Available memory in the buffer. + * + * @retval NRF_SUCCESS If the encoding was successful. + * @retval NRF_ERROR_NO_MEM If available memory was not enough. + * @retval NRF_ERROR_xxx If any other error occured. + */ +static ret_code_t nfc_ep_oob_bluetooth_device_address_encode(uint8_t * const p_encoded_data, + uint16_t max_len) +{ + ret_code_t err_code = NRF_SUCCESS; + ble_gap_addr_t device_address; + + memset(&device_address, 0x00, sizeof(device_address)); + + if (NFC_EP_OOB_REC_GAP_ADDR_LEN > max_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Get BLE address */ + err_code = sd_ble_gap_addr_get(&device_address); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + /* Encode Bluetooth EP device address */ + memcpy(p_encoded_data, device_address.addr, NFC_EP_OOB_REC_GAP_ADDR_LEN); + + return NRF_SUCCESS; +} + +ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t * p_ad_data = NULL; + uint16_t payload_len, ad_data_len; + + /* Check correctness of the configuration structure */ + err_code = nfc_ep_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + if (p_buff != NULL) + { + /* Validate if there is enough memory for OOB payload length field and BLE device address */ + if (NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Set proper memory offset in payload buffer for AD structure and count available memory. + * Bluetooth EP device address and OOB payload length field must be inserted before the AD payload */ + p_ad_data = (uint8_t *) (p_buff + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN); + ad_data_len = *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if ( *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > UINT16_MAX ) + { + ad_data_len = UINT16_MAX; + } + } + + /* Encode AD structures into NFC record payload */ + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_ad_data, &ad_data_len); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Now as the final payload length is known OOB payload length field, and Bluetooth device + * address can be encoded */ + payload_len = ad_data_len + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if (p_buff != NULL) + { + p_buff += uint16_encode(payload_len, p_buff); + err_code = nfc_ep_oob_bluetooth_device_address_encode(p_buff, p_ad_data - p_buff); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + } + + /* Update total payload length */ + *p_len = payload_len; + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_EP_OOB_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h new file mode 100644 index 0000000..1b7be22 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h @@ -0,0 +1,135 @@ +/** + * 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 NFC_EP_OOB_REC_H__ +#define NFC_EP_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_ep_oob_rec EP OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF EP OOB records for NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Size of the type field of the Bluetooth Carrier Configuration EP record, defined in the + * file @c nfc_ep_oob_rec.c. It is used in the @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF macro. + */ +#define NFC_EP_OOB_REC_TYPE_LENGTH 32 + +/** + * @brief External reference to the type field of the Bluetooth Carrier Configuration EP record, defined + * in the file @c nfc_ep_oob_rec.c. It is used in the @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF macro. + */ +extern const uint8_t ndef_ep_oob_record_type[NFC_EP_OOB_REC_TYPE_LENGTH]; + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration EP record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If available memory was not enough for record payload to be encoded. + * @retval Other If any other error occurred during record payload encoding. + */ +ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len); + +/** @brief Macro for generating a description of an NFC NDEF Bluetooth Carrier Configuration EP record. + * + * This macro declares and initializes an instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration EP record. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_ble_simplified_ep_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] NAME Name for accessing record descriptor. + * @param[in] PAYLOAD_ID NDEF record header Payload ID field (Limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] P_BLE_ADVDATA Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + */ +#define NFC_NDEF_EP_OOB_RECORD_DESC_DEF(NAME, \ + PAYLOAD_ID, \ + P_BLE_ADVDATA) \ + uint8_t NAME##_ndef_ep_oob_record_id = (PAYLOAD_ID); \ + uint8_t NAME##_ndef_ep_oob_record_id_length = ((PAYLOAD_ID) != 0) ? 1 : 0; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \ + TNF_MEDIA_TYPE, \ + &NAME##_ndef_ep_oob_record_id, \ + NAME##_ndef_ep_oob_record_id_length, \ + (ndef_ep_oob_record_type), \ + sizeof(ndef_ep_oob_record_type), \ + nfc_ep_oob_payload_constructor, \ + (P_BLE_ADVDATA)) \ + +/** + * @brief Macro for accessing the NFC NDEF Bluetooth Carrier Configuration EP record descriptor + * instance that was created with @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF. + */ +#define NFC_NDEF_EP_OOB_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_EP_OOB_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c new file mode 100644 index 0000000..b453087 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c @@ -0,0 +1,107 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_HS_REC) + +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nrf_error.h" + +#define HS_REC_VERSION_SIZE 1 + +const uint8_t nfc_hs_rec_type_field[] = {'H', 's'}; ///< Handover Select record type. + + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_buff != NULL) + { + // There must be at least 1 free byte in buffer for version byte. + if (*p_len < HS_REC_VERSION_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + // Major/minor version byte. + *p_buff = ( (p_nfc_hs_rec_payload_desc->major_version << 4) & 0xF0) | + ( p_nfc_hs_rec_payload_desc->minor_version & 0x0F); + p_buff += HS_REC_VERSION_SIZE; + + // Decrement remaining buffer size. + *p_len -= HS_REC_VERSION_SIZE; + } + + // Encode local records encapsulated in a message. + err_code = nfc_ndef_msg_encode(p_nfc_hs_rec_payload_desc->p_local_records, p_buff, p_len); + if (err_code!= NRF_SUCCESS) + { + return err_code; + } + + // Add version byte to the total record size. + *p_len += HS_REC_VERSION_SIZE; + + return NRF_SUCCESS; +} + + +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + nfc_ndef_msg_clear(p_hs_payload->p_local_records); +} + + +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + return nfc_ndef_msg_record_add(p_hs_payload->p_local_records, p_local_rec); +} + +#endif // NRF_MODULE_ENABLED(NFC_HS_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h new file mode 100644 index 0000000..0d0d88b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h @@ -0,0 +1,165 @@ +/** + * 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 NFC_HS_REC_H__ +#define NFC_HS_REC_H__ + +/**@file + * + * @defgroup nfc_hs_rec Hs (Handover Select) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Handover Select records for NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_record.h" +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Handover Select record payload descriptor. + */ +typedef struct +{ + uint8_t major_version; ///< Major version number of the supported Connection Handover specification. + uint8_t minor_version; ///< Minor version number of the supported Connection Handover specification. + nfc_ndef_msg_desc_t * p_local_records; ///< Pointer to a message encapsulating local records. +} nfc_hs_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Handover Select record payload. + * + * This function encodes the payload of a Handover Select record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief An external reference to the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_hs_rec_type_field[]; + +/** + * @brief Size of the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +#define NFC_HS_REC_TYPE_LENGTH 2 + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a Handover Select record. + * + * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and + * an instance of type @ref nfc_hs_rec_payload_desc_t, which together constitute an instance of a Handover Select record. + * + * Use the macro @ref NFC_NDEF_HS_RECORD_DESC to access the NDEF Handover Select record descriptor instance. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_ble_full_handover_select_msg_encode) + * must be done in the same variable scope. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] MAJOR_VERSION Major version number of the supported Connection Handover specification. + * @param[in] MINOR_VERSION Minor version number of the supported Connection Handover specification. + * @param[in] MAX_RECORDS Maximum number of local records (ac records plus optional err record). + */ +#define NFC_NDEF_HS_RECORD_DESC_DEF(NAME, \ + MAJOR_VERSION, \ + MINOR_VERSION, \ + MAX_RECORDS) \ + NFC_NDEF_MSG_DEF(NAME, MAX_RECORDS); \ + nfc_hs_rec_payload_desc_t NAME##_nfc_hs_rec_payload_desc = \ + { \ + .major_version = MAJOR_VERSION, \ + .minor_version = MINOR_VERSION, \ + .p_local_records = &NFC_NDEF_MSG(NAME) \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_hs_rec_type_field, \ + NFC_HS_REC_TYPE_LENGTH, \ + nfc_hs_rec_payload_constructor, \ + &(NAME##_nfc_hs_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Handover Select record descriptor + * instance that was created with @ref NFC_NDEF_HS_RECORD_DESC_DEF. + */ +#define NFC_NDEF_HS_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing local records in the NFC NDEF Handover Select record. + * + * This function clears local records from the Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to the Handover Select record descriptor. + */ +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec); + +/** + * @brief Function for adding a local record to an NFC NDEF Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to a Handover Select record. + * @param[in] p_local_rec Pointer to a local record to add. + * + * @retval NRF_SUCCESS If the local record was added successfully. + * @retval NRF_ERROR_NO_MEM If the Handover Select record already contains the maximum number of local records. + */ +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_HS_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c new file mode 100644 index 0000000..95d939f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c @@ -0,0 +1,106 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_LE_OOB_REC) + +#include "nfc_le_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "nfc_ble_pair_common.h" + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration LE record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields are required. Security Manager Out Of Band Flags structure must not be included. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_le_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((false == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT == p_ble_advdata->le_role) || + (NULL != p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + +ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + /* Check correctness of the configuration structure */ + err_code = nfc_le_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Encode AD structures into NFC record payload */ + uint16_t buff_len = *p_len; + if (*p_len > UINT16_MAX) + { + buff_len = UINT16_MAX; + } + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_buff, &buff_len); + + /* Update total payload length */ + *p_len = (uint32_t) buff_len; + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_LE_OOB_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h new file mode 100644 index 0000000..6671671 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h @@ -0,0 +1,123 @@ +/** + * 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 NFC_LE_OOB_REC_H__ +#define NFC_LE_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_le_oob_rec LE OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF LE OOB records for NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" +#include "nfc_ble_pair_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration LE record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval Other If the record payload encoding failed. + */ +ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len); + +/** @brief Macro for generating a description of an NFC NDEF Bluetooth Carrier Configuration LE Record. + * + * This macro declares and initializes an instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration LE record. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_ble_simplified_le_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] NAME Name for accessing record descriptor. + * @param[in] PAYLOAD_ID NDEF record header Payload ID field (Limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] P_BLE_ADVDATA Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + */ +#define NFC_NDEF_LE_OOB_RECORD_DESC_DEF(NAME, \ + PAYLOAD_ID, \ + P_BLE_ADVDATA) \ + uint8_t NAME##_ndef_le_oob_record_id = (PAYLOAD_ID); \ + uint8_t NAME##_ndef_le_oob_record_id_length = ((PAYLOAD_ID) != 0) ? 1 : 0; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \ + TNF_MEDIA_TYPE, \ + &NAME##_ndef_le_oob_record_id, \ + NAME##_ndef_le_oob_record_id_length, \ + (le_oob_rec_type_field), \ + sizeof(le_oob_rec_type_field), \ + nfc_le_oob_payload_constructor, \ + (P_BLE_ADVDATA)) \ + +/** + * @brief Macro for accessing the NFC NDEF Bluetooth Carrier Configuration LE record descriptor + * instance that was created with @ref NFC_NDEF_LE_OOB_RECORD_DESC_DEF. + */ +#define NFC_NDEF_LE_OOB_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LE_OOB_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c new file mode 100644 index 0000000..b1796af --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c @@ -0,0 +1,183 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG) + +#include "app_util.h" +#include "nfc_ndef_msg.h" +#include "nordic_common.h" +#include "nrf.h" + + +/** + * @brief Resolve the value of record location flags of the NFC NDEF record within an NFC NDEF message. + */ +__STATIC_INLINE nfc_ndef_record_location_t record_location_get(uint32_t index, + uint32_t record_count) +{ + nfc_ndef_record_location_t record_location; + + if (index == 0) + { + if (record_count == 1) + { + record_location = NDEF_LONE_RECORD; + } + else + { + record_location = NDEF_FIRST_RECORD; + } + } + else if (record_count == index + 1) + { + record_location = NDEF_LAST_RECORD; + } + else + { + record_location = NDEF_MIDDLE_RECORD; + } + + return record_location; +} + + +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len) +{ + nfc_ndef_record_location_t record_location; + uint32_t temp_len; + uint32_t i; + uint32_t err_code; + + uint32_t sum_of_len = 0; + + if ((p_ndef_msg_desc == NULL) || p_msg_len == NULL) + { + return NRF_ERROR_NULL; + } + + nfc_ndef_record_desc_t * * pp_record_rec_desc = p_ndef_msg_desc->pp_record; + + if (p_ndef_msg_desc->pp_record == NULL) + { + return NRF_ERROR_NULL; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + uint8_t * p_root_msg_buffer = p_msg_buffer; + + if (p_msg_buffer != NULL) + { + if (*p_msg_len < NLEN_FIELD_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + p_msg_buffer += NLEN_FIELD_SIZE; + } + sum_of_len += NLEN_FIELD_SIZE; +#endif + + for (i = 0; i < p_ndef_msg_desc->record_count; i++) + { + record_location = record_location_get(i, p_ndef_msg_desc->record_count); + + temp_len = *p_msg_len - sum_of_len; + + err_code = nfc_ndef_record_encode(*pp_record_rec_desc, + record_location, + p_msg_buffer, + &temp_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + sum_of_len += temp_len; + if (p_msg_buffer != NULL) + { + p_msg_buffer += temp_len; + } + + /* next record */ + pp_record_rec_desc++; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + if (p_msg_buffer != NULL) + { + if (sum_of_len - NLEN_FIELD_SIZE > UINT16_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + UNUSED_RETURN_VALUE(uint16_big_encode(sum_of_len - NLEN_FIELD_SIZE, p_root_msg_buffer)); + } +#endif + + *p_msg_len = sum_of_len; + + return NRF_SUCCESS; +} + + +void nfc_ndef_msg_clear(nfc_ndef_msg_desc_t * p_msg) +{ + p_msg->record_count = 0; +} + + +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record) +{ + if (p_msg->record_count >= p_msg->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_msg->pp_record[p_msg->record_count] = p_record; + p_msg->record_count++; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h new file mode 100644 index 0000000..9ca15f3 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h @@ -0,0 +1,197 @@ +/** + * 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 NFC_NDEF_MSG_H__ +#define NFC_NDEF_MSG_H__ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@file + * + * @defgroup nfc_ndef_msg Custom NDEF messages + * @{ + * @ingroup nfc_modules + * + * @brief Generation of NFC NDEF messages for the NFC tag. + * + */ + +#define TYPE_4_TAG 4U ///< Type 4 Tag identifier. +#define NLEN_FIELD_SIZE 2U ///< Size of NLEN field, used to encode NDEF message for Type 4 Tag. + + /** + * @brief NDEF message descriptor. + */ + typedef struct { + nfc_ndef_record_desc_t ** pp_record; ///< Pointer to an array of pointers to NDEF record descriptors. + uint32_t max_record_count; ///< Number of elements in the allocated pp_record array, which defines the maximum number of records within the NDEF message. + uint32_t record_count; ///< Number of records in the NDEF message. + } nfc_ndef_msg_desc_t; + + /** + * @brief Function for encoding an NDEF message. + * + * This function encodes an NDEF message according to the provided message descriptor. + * + * @note The way of encoding an NDEF message may vary depending on tag's platform, which + * can be chosen with @ref NFC_NDEF_MSG_TAG_TYPE in @c sdk_config.h. + * + * @param[in] p_ndef_msg_desc Pointer to the message descriptor. + * @param[out] p_msg_buffer Pointer to the message destination. If NULL, function will + * calculate the expected size of the message. + * @param[in,out] p_msg_len Size of the available memory for the message as input. Size of + * the generated message as output. + * + * @return Return value from @ref nfc_ndef_record_encode. + */ +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len); + +/** + * @brief Function for clearing an NDEF message. + * + * This function clears an NDEF message descriptor, thus empties the NDEF message. + * + * @param[in,out] p_msg Pointer to the message descriptor. + */ +void nfc_ndef_msg_clear( nfc_ndef_msg_desc_t * p_msg); + +/** + * @brief Function for adding a record to an NDEF message. + * + * @param[in] p_record Pointer to the record descriptor. + * @param[in,out] p_msg Pointer to the message descriptor. + * + * @retval NRF_SUCCESS If the record was added successfully. + * @retval NRF_ERROR_NO_MEM If the message already contains the maximum number of records and the operation is not allowed. + */ +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record); + + +/**@brief Macro for creating and initializing an NFC NDEF message descriptor. + * + * This macro creates and initializes an instance of type @ref nfc_ndef_msg_desc_t + * and an array of pointers to record descriptors (@ref nfc_ndef_record_desc_t) used + * by the message. + * + * Use the macro @ref NFC_NDEF_MSG to access the NDEF message descriptor instance. + * + * @note The message descriptor is declared as automatic variable, which implies that + * the NDEF message encoding must be done in the same variable scope. + * + * @param[in] NAME Name of the related instance. + * @param[in] MAX_RECORD_CNT Maximal count of records in the message. + */ +#define NFC_NDEF_MSG_DEF(NAME, MAX_RECORD_CNT) \ + nfc_ndef_record_desc_t * NAME##_nfc_ndef_p_record_desc_array[MAX_RECORD_CNT]; \ + nfc_ndef_msg_desc_t NAME##_nfc_ndef_msg_desc = \ + { \ + .pp_record = NAME##_nfc_ndef_p_record_desc_array, \ + .max_record_count = MAX_RECORD_CNT, \ + .record_count = 0 \ + } + +/** @brief Macro for accessing the NFC NDEF message descriptor instance + * that you created with @ref NFC_NDEF_MSG_DEF. + */ +#define NFC_NDEF_MSG(NAME) (NAME##_nfc_ndef_msg_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor with an encapsulated NDEF message. + + * This macro creates and initializes a static instance of type + * @ref nfc_ndef_record_desc_t that contains an encapsulated NDEF message as + * payload. @ref nfc_ndef_msg_encode is used as payload constructor to encode + * the message. The encoded message is then used as payload for the record. + * + * Use the macro @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD to access the NDEF record descriptor instance. + * + * @note The message descriptor is declared as automatic variable, which implies that + * the NDEF message encoding must be done in the same variable scope. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_NESTED_MESSAGE Pointer to the message descriptor to encapsulate + * as the record's payload. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF( NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_NESTED_MESSAGE ) \ + nfc_ndef_record_desc_t NAME##_ndef_record_nested_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)(nfc_ndef_msg_encode), \ + .p_payload_descriptor = (void*) (P_NESTED_MESSAGE) \ + } + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD(NAME) (NAME##_ndef_record_nested_desc) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c new file mode 100644 index 0000000..9397236 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c @@ -0,0 +1,191 @@ +/** + * 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. + * + */ +#include "sdk_config.h" +#include "nordic_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD) + +#include <string.h> +#include "nfc_ndef_record.h" +#include "app_util.h" +#include "nrf.h" + + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in long NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SIZE (2 + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE) + +__STATIC_INLINE uint32_t record_header_size_calc(nfc_ndef_record_desc_t const * p_ndef_record_desc) +{ + uint32_t len = NDEF_RECORD_BASE_LONG_SIZE; + + len += p_ndef_record_desc->id_length + p_ndef_record_desc->type_length; + + if (p_ndef_record_desc->id_length > 0) + { + len++; + } + + return len; +} + + +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len) +{ + uint8_t * p_flags; // use as pointer to TNF + flags field + uint8_t * p_payload_len = NULL; // use as pointer to payload length field + uint32_t record_payload_len; + + if (p_ndef_record_desc == NULL) + { + return NRF_ERROR_NULL; + } + + // count record length without payload + uint32_t record_header_len = record_header_size_calc(p_ndef_record_desc); + uint32_t err_code = NRF_SUCCESS; + + if (p_record_buffer != NULL) + { + /* verify location range */ + if ((record_location & (~NDEF_RECORD_LOCATION_MASK)) != 0x00) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* verify if there is enough available memory */ + if (record_header_len > *p_record_len) + { + return NRF_ERROR_NO_MEM; + } + + p_flags = p_record_buffer; + p_record_buffer++; + + // set location bits and clear other bits in 1st byte. + *p_flags = record_location; + + *p_flags |= p_ndef_record_desc->tnf; + + /* TYPE LENGTH */ + *(p_record_buffer++) = p_ndef_record_desc->type_length; + + // use always long record and remember payload len field memory offset. + p_payload_len = p_record_buffer; + p_record_buffer += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + + /* ID LENGTH - option */ + if (p_ndef_record_desc->id_length > 0) + { + *(p_record_buffer++) = p_ndef_record_desc->id_length; + + /* IL flag */ + *p_flags |= NDEF_RECORD_IL_MASK; + } + + /* TYPE */ + memcpy(p_record_buffer, p_ndef_record_desc->p_type, p_ndef_record_desc->type_length); + p_record_buffer += p_ndef_record_desc->type_length; + + /* ID */ + if (p_ndef_record_desc->id_length > 0) + { + memcpy(p_record_buffer, p_ndef_record_desc->p_id, p_ndef_record_desc->id_length); + p_record_buffer += p_ndef_record_desc->id_length; + } + + // count how much memory is left in record buffer for payload field. + record_payload_len = (*p_record_len - record_header_len); + } + + /* PAYLOAD */ + if (p_ndef_record_desc->payload_constructor != NULL) + { + err_code = + p_ndef_record_desc->payload_constructor(p_ndef_record_desc->p_payload_descriptor, + p_record_buffer, + &record_payload_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_NULL; + } + + if (p_record_buffer != NULL) + { + /* PAYLOAD LENGTH */ + (void) uint32_big_encode(record_payload_len, p_payload_len); + } + + *p_record_len = record_header_len + record_payload_len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len) +{ + + if (p_buffer != NULL) + { + if ( *p_len < p_payload_descriptor->payload_length) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_buffer, + p_payload_descriptor->p_payload, + p_payload_descriptor->payload_length); + } + + *p_len = p_payload_descriptor->payload_length; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h new file mode 100644 index 0000000..069258c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h @@ -0,0 +1,311 @@ +/** + * 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 NFC_NDEF_RECORD_H__ +#define NFC_NDEF_RECORD_H__ + +#include <stdint.h> +#include <string.h> +#include "compiler_abstraction.h" +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record Custom NDEF records + * @{ + * @ingroup nfc_ndef_msg + * + * @brief Generation of NFC NDEF records for NFC messages. + * + */ + + +#define NDEF_RECORD_IL_MASK 0x08 ///< Mask of the ID field presence bit in the flags byte of an NDEF record. +#define NDEF_RECORD_TNF_MASK 0x07 ///< Mask of the TNF value field in the first byte of an NDEF record. +#define NDEF_RECORD_SR_MASK 0x10 ///< Mask of the SR flag. If set, this flag indicates that the PAYLOAD_LENGTH field has a size of 1 byte. Otherwise, PAYLOAD_LENGTH has 4 bytes. +#define NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE 4 ///< Size of the Payload Length field in a long NDEF record. +#define NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE 1 ///< Size of the Payload Length field in a short NDEF record. +#define NDEF_RECORD_ID_LEN_SIZE 1 ///< Size of the ID Length field in an NDEF record. + + +/** + * @brief Payload constructor type. + + * A payload constructor is a function for constructing the payload of an NDEF + * record. + * + * @param[in] p_payload_descriptor Pointer to the input data for the constructor. + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. Size of the generated + * record payload as output. The implementation must check if the payload + * will fit in the provided buffer. This must be checked by the caller function. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +typedef ret_code_t (* p_payload_constructor_t)(void * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + + +/** + * @brief Type Name Format (TNF) Field Values. + * + * Values to specify the TNF of a record. + */ +typedef enum +{ + TNF_EMPTY = 0x00, ///< The value indicates that there is no type or payload associated with this record. + TNF_WELL_KNOWN = 0x01, ///< NFC Forum well-known type [NFC RTD]. + TNF_MEDIA_TYPE = 0x02, ///< Media-type as defined in RFC 2046 [RFC 2046]. + TNF_ABSOLUTE_URI = 0x03, ///< Absolute URI as defined in RFC 3986 [RFC 3986]. + TNF_EXTERNAL_TYPE = 0x04, ///< NFC Forum external type [NFC RTD]. + TNF_UNKNOWN_TYPE = 0x05, ///< The value indicates that there is no type associated with this record. + TNF_UNCHANGED = 0x06, ///< The value is used for the record chunks used in chunked payload. + TNF_RESERVED = 0x07, ///< The value is reserved for future use. +} nfc_ndef_record_tnf_t; + + +/** + * @brief NDEF record descriptor. + */ +typedef struct +{ + nfc_ndef_record_tnf_t tnf; ///< Value of the Type Name Format (TNF) field. + + uint8_t id_length; ///< Length of the ID field. If 0, a record format without ID field is assumed. + uint8_t const * p_id; ///< Pointer to the ID field data. Not relevant if id_length is 0. + + uint8_t type_length; ///< Length of the type field. + uint8_t const * p_type; ///< Pointer to the type field data. Not relevant if type_length is 0. + + p_payload_constructor_t payload_constructor; ///< Pointer to the payload constructor function. + void * p_payload_descriptor; ///< Pointer to the data for the payload constructor function. + +} nfc_ndef_record_desc_t; + +/** + * @brief Record position within the NDEF message. + * + * Values to specify the location of a record within the NDEF message. + */ +typedef enum +{ + NDEF_FIRST_RECORD = 0x80, ///< First record. + NDEF_MIDDLE_RECORD = 0x00, ///< Middle record. + NDEF_LAST_RECORD = 0x40, ///< Last record. + NDEF_LONE_RECORD = 0xC0 ///< Only one record in the message. +} nfc_ndef_record_location_t; + +#define NDEF_RECORD_LOCATION_MASK (NDEF_LONE_RECORD) ///< Mask of the Record Location bits in the NDEF record's flags byte. + +/** + * @brief Binary data descriptor containing the payload for the record. + */ +typedef struct +{ + uint8_t const * p_payload; ///< Pointer to the buffer with the data. + uint32_t payload_length; ///< Length of data in bytes. +} nfc_ndef_bin_payload_desc_t; + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a generic record. + * + * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t. + * + * Use the macro @ref NFC_NDEF_GENERIC_RECORD_DESC to access the NDEF record descriptor instance. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF record encoding must be done in the same variable scope. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD_CONSTRUCTOR Pointer to the payload constructor function. + * The constructor must be of type @ref p_payload_constructor_t. + * @param[in] P_PAYLOAD_DESCRIPTOR Pointer to the data for the payload constructor. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD_CONSTRUCTOR, \ + P_PAYLOAD_DESCRIPTOR) \ + nfc_ndef_record_desc_t NAME##_ndef_generic_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)P_PAYLOAD_CONSTRUCTOR, \ + .p_payload_descriptor = (void *) P_PAYLOAD_DESCRIPTOR \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_GENERIC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC(NAME) (NAME##_ndef_generic_record_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a record with + * binary payload. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and a binary data descriptor containing the payload data. + * + * Use the macro @ref NFC_NDEF_RECORD_BIN_DATA to access the NDEF record descriptor instance. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF record encoding must be done in the same variable scope. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD Pointer to the payload data that will be copied to the payload field. + * @param[in] PAYLOAD_LEN Length of the payload. + */ +#define NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \ + TNF, \ + P_ID, ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD, \ + PAYLOAD_LEN) \ + nfc_ndef_bin_payload_desc_t NAME##_nfc_ndef_bin_payload_desc = \ + { \ + .p_payload = P_PAYLOAD, \ + .payload_length = PAYLOAD_LEN \ + }; \ + \ + nfc_ndef_record_desc_t NAME##_nfc_ndef_bin_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy, \ + .p_payload_descriptor = (void *) &NAME##_nfc_ndef_bin_payload_desc \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_RECORD_BIN_DATA(NAME) (NAME##_nfc_ndef_bin_record_desc) + +/** @brief Macro for accessing the binary data descriptor that contains + * the payload of the record that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_BIN_PAYLOAD_DESC(NAME) (NAME##_nfc_ndef_bin_payload_desc) + +/** + * @brief Function for encoding an NDEF record. + * + * This function encodes an NDEF record according to the provided record descriptor. + * + * @param[in] p_ndef_record_desc Pointer to the record descriptor. + * @param[in] record_location Location of the record within the NDEF message. + * @param[out] p_record_buffer Pointer to the record destination. If NULL, function will + * calculate the expected size of the record. + * @param[in,out] p_record_len Size of the available memory for the record as input. Size of the generated + * record as output. + * + * @retval NRF_SUCCESS If the record was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted record size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If the location of the record is erroneous. + * @retval Other Other codes might be returned depending on the NDEF record payload constructor implementation. + */ +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len); + +/** + * @brief Function for constructing the payload for an NFC NDEF record from binary data. + * + * This function copies data from a binary buffer to the payload field of the NFC NDEF record. + * + * @param[in] p_payload_descriptor Pointer to the descriptor of the binary data location and size. + * + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * @param[in,out] p_len Size of the available memory for the payload as input. Size of the copied payload + * as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_H__ + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c new file mode 100644 index 0000000..6ec240f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c @@ -0,0 +1,97 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_MSG) + +#include <stdint.h> +#include <string.h> +#include "nfc_launchapp_rec.h" +#include "nfc_launchapp_msg.h" +#include "nrf_error.h" +#include "sdk_macros.h" + +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + + /* Create NFC NDEF message description, capacity - 2 records */ + NFC_NDEF_MSG_DEF(nfc_launchapp_msg, 2); + + /* Create NFC NDEF Windows Phone LaunchApp Record description */ + NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF(nfc_win_launchapp_rec, + p_win_app_id, + win_app_id_length); + + /* Create NFC NDEF Android Application Record description */ + NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF(nfc_and_launchapp_rec, + p_android_package_name, + android_package_name_length); + + if (p_win_app_id != NULL) + { + /* Add Windows Phone LaunchApp Record as first record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), + &NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC(nfc_win_launchapp_rec)); + VERIFY_SUCCESS(err_code); + } + if (p_android_package_name != NULL) + { + /* Add Android Application Record as second record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), + &NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC(nfc_and_launchapp_rec)); + VERIFY_SUCCESS(err_code); + } + VERIFY_FALSE(NFC_NDEF_MSG(nfc_launchapp_msg).record_count == 0, + NRF_ERROR_INVALID_PARAM); + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_launchapp_msg), + p_buf, + p_len); + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_MSG) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h new file mode 100644 index 0000000..90cf9ed --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h @@ -0,0 +1,100 @@ +/** + * 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 NFC_LAUNCHAPP_MSG_H__ +#define NFC_LAUNCHAPP_MSG_H__ + +/** @file + * + * @defgroup nfc_launchapp_msg Launch app messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages that can be used to launch apps. + * + */ + +#include <stdint.h> +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function for encoding an NFC NDEF launch app message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode + */ +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + #endif // NFC_LAUNCHAPP_MSG_H__ + + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c new file mode 100644 index 0000000..8e586b3 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c @@ -0,0 +1,107 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_REC) + +#include "nfc_launchapp_rec.h" +#include <string.h> +#include "nrf_error.h" +#include "app_util.h" +#include "nfc_ndef_record.h" + +/* Record Payload Type for NFC NDEF Android Application Record */ +const uint8_t ndef_android_launchapp_rec_type[] = +{ + 'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', 'c','o', 'm', ':', 'p', 'k', 'g' +}; + +/* Record Payload Type for NFC NDEF Windows LaunchApp record */ +const uint8_t ndef_windows_launchapp_rec_type[] = +{ + 'w', 'i', 'n', 'd', 'o', 'w', 's', '.', 'c', 'o', 'm', '/', 'L', 'a', 'u', + 'n', 'c', 'h', 'A', 'p', 'p' +}; +/* Platform type used in Record Payload of NFC NDEF Windows LaunchApp record */ +const uint8_t ndef_windows_launchapp_plat_type[] = +{ + 'W', 'i', 'n', 'd', 'o', 'w', 's', 'P', 'h', 'o', 'n', 'e' +}; + +#define WIN_LAUNCHAPP_EMPTY_PARAMETER 0x20 ///< The empty parameter value for the Windows LaunchApp Record. + +ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + + win_launchapp_payload_desc_t * launch_desc = (win_launchapp_payload_desc_t *) p_input; + + uint32_t temp_len = (uint32_t)launch_desc->platform_length + launch_desc->app_id_length + 7; + + if (p_buff != NULL) + { + if (temp_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff++ = 0x00; // platform count: 1 + *p_buff++ = 0x01; // -||- + + *p_buff++ = launch_desc->platform_length; + memcpy(p_buff, launch_desc->platform, launch_desc->platform_length); // platform + p_buff += launch_desc->platform_length; + + + *p_buff++ = launch_desc->app_id_length; + memcpy(p_buff, launch_desc->app_id, launch_desc->app_id_length); + p_buff += launch_desc->app_id_length; + + *p_buff++ = 0x00; // parameters length 1B + *p_buff++ = 0x01; // -||- + *p_buff++ = WIN_LAUNCHAPP_EMPTY_PARAMETER; // empty parameter + } + + *p_len = temp_len; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h new file mode 100644 index 0000000..a923e69 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h @@ -0,0 +1,205 @@ +/** + * 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 NFC_LAUNCHAPP_REC_H__ +#define NFC_LAUNCHAPP_REC_H__ + +/**@file + * + * @defgroup nfc_launchapp_rec Launch app records + * @{ + * @ingroup nfc_launchapp_msg + * + * @brief Generation of NFC NDEF record descriptions that launch apps. + * + */ + +#include <stdint.h> +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Size of the type field of the Android Application Record, defined in the file + * @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC macro. + */ +#define NFC_ANDROID_REC_TYPE_LENGTH 15 + +/** + * @brief Size of the type field of the Windows LaunchApp Record, defined in the file + * @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro. + */ +#define NFC_WINDOWS_REC_TYPE_LENGTH 21 + +/** + * @brief Size of the platform type, which is used to encode payload field of the Windows LaunchApp + * Record, defined in the file @c nfc_launchapp_rec.c. It is used in the + * @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro. + */ +#define NFC_WINDOWS_PLAT_TYPE_LENGTH 12 + +/** + * @brief Type of description of payload of Windows LaunchApp record. + */ +typedef struct +{ + const uint8_t * platform; + uint8_t platform_length; + const uint8_t * app_id; + uint8_t app_id_length; +} win_launchapp_payload_desc_t; + +/** + * @brief External reference to the type field of the NFC NDEF Android Application Record, defined in the + * file @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF macro. + */ +extern const uint8_t ndef_android_launchapp_rec_type[NFC_ANDROID_REC_TYPE_LENGTH]; + +/** + * @brief External reference to the type field of the NFC NDEF Windows LaunchApp record, defined in the + * file @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro. + */ +extern const uint8_t ndef_windows_launchapp_rec_type[NFC_WINDOWS_REC_TYPE_LENGTH]; + +/** + * @brief External reference to the platform type, which is used to encode payload field of the NFC NDEF + * Windows LaunchApp record. This constant is defined in the file @c nfc_launchapp_rec.c and is used in + * the macro @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF. + */ +extern const uint8_t ndef_windows_launchapp_plat_type[NFC_WINDOWS_PLAT_TYPE_LENGTH]; + +/** + * @brief Function for constructing the payload for a Windows LaunchApp record. + * + * This function encodes the payload according to the LaunchApp record definition. It implements an API + * compatible with p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the LaunchApp record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS Always success. + */ +ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len); + +/** @brief Macro for generating a description of an NFC NDEF Android Application Record (AAR). + * + * This macro declares and initializes an instance of an NFC NDEF record description + * of an Android Application Record (AAR). + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_launchapp_msg_encode) must be done + * in the same variable scope. + * + * @param[in] NAME Name for accessing record descriptor. + * @param[in] P_PACKAGE_NAME Pointer to the Android package name string. + * @param[in] PACKAGE_NAME_LENGTH Length of the Android package name. + */ +#define NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF(NAME, \ + P_PACKAGE_NAME, \ + PACKAGE_NAME_LENGTH) \ + NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \ + TNF_EXTERNAL_TYPE, \ + NULL, \ + 0, \ + ndef_android_launchapp_rec_type, \ + sizeof(ndef_android_launchapp_rec_type), \ + (P_PACKAGE_NAME), \ + (PACKAGE_NAME_LENGTH)) + +/** + * @brief Macro for accessing the NFC NDEF Android Application Record descriptor + * instance that was created with @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF. + */ +#define NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC(NAME) NFC_NDEF_RECORD_BIN_DATA(NAME) + +/** @brief Macro for generating a description of an NFC NDEF Windows LaunchApp record. + * + * This macro declares and initializes an instance of an NFC NDEF record description + * of a Windows LaunchApp record. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_launchapp_msg_encode) must be done + * in the same variable scope. + * + * @param[in] NAME Name for accessing record descriptor. + * @param[in] P_WIN_APP_ID Pointer to the Windows application ID string (GUID). + * @param[in] WIN_APP_ID_LENGTH Length of the Windows application ID. + * + * @return Pointer to the description of the record. + */ +#define NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF(NAME, \ + P_WIN_APP_ID, \ + WIN_APP_ID_LENGTH) \ + win_launchapp_payload_desc_t NAME##_ndef_win_launchapp_rec_payload_desc = \ + { \ + .platform = ndef_windows_launchapp_plat_type, \ + .platform_length = sizeof(ndef_windows_launchapp_plat_type), \ + .app_id = (P_WIN_APP_ID), \ + .app_id_length = WIN_APP_ID_LENGTH \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_ABSOLUTE_URI, \ + NULL, \ + 0, \ + ndef_windows_launchapp_rec_type, \ + sizeof(ndef_windows_launchapp_rec_type), \ + nfc_win_launchapp_payload_constructor, \ + &NAME##_ndef_win_launchapp_rec_payload_desc) \ + +/** + * @brief Macro for accessing the NFC NDEF Windows LaunchApp Record descriptor + * instance that was created with @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF. + */ +#define NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LAUNCHAPP_REC diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c new file mode 100644 index 0000000..f4ee3e2 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c @@ -0,0 +1,94 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME nfc_ndef_msg_parser +#if NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_MSG_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_MSG_PARSER_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_NDEF_MSG_PARSER_LOG_ENABLED + +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + ret_code_t ret_code; + nfc_ndef_parser_memo_desc_t parser_memory_helper; + + ret_code = ndef_parser_memo_resolve(p_result_buf, + p_result_buf_len, + &parser_memory_helper); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + ret_code = internal_ndef_msg_parser(&parser_memory_helper, + p_nfc_data, + p_nfc_data_len); + + return ret_code; +} + + +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc) +{ + uint32_t i; + + NRF_LOG_INFO("NDEF message contains %d record(s)", p_msg_desc->record_count); + + for (i = 0; i < p_msg_desc->record_count; i++) + { + ndef_record_printout(i, p_msg_desc->pp_record[i]); + } +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h new file mode 100644 index 0000000..dde1653 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h @@ -0,0 +1,123 @@ +/** + * 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. + * + */ +#ifndef NFC_NDEF_MSG_PARSER_H__ +#define NFC_NDEF_MSG_PARSER_H__ + +/**@file + * + * @defgroup nfc_ndef_parser NDEF message parser + * @{ + * @ingroup nfc_modules + * + * @brief Parser for NFC NDEF messages and records. + * + * @defgroup nfc_ndef_msg_parser Parser for NDEF messages + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_msg_parser_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro for calculating the memory size required for holding the + * description of a message that consists of a certain number of NDEF records. + * + * @param[in] max_count_of_records Maximum number of records to hold. + */ +#define NFC_NDEF_PARSER_REQIRED_MEMO_SIZE_CALC(max_count_of_records) \ + ((uint32_t)(max_count_of_records) <= 1) ? \ + (sizeof(parsed_ndef_msg_1_t) * (uint32_t)(max_count_of_records)) : \ + (sizeof(parsed_ndef_msg_1_t) + ((NFC_PARSER_M_DELTA) *((uint32_t)(max_count_of_records) - 1))) + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This function parses NDEF messages using NDEF binary record descriptors. + * + * @param[out] p_result_buf Pointer to the buffer that will be used to hold + * the NDEF message descriptor. After parsing is completed successfully, the first address + * in the buffer is filled by the NDEF message descriptor + * (@ref nfc_ndef_msg_desc_t), which provides a full description of + * the parsed NDEF message. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message or + * the buffer is too small to hold the actual result of the parsing. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of the provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + */ +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of an NDEF message. + * + * @param[in] p_msg_desc Pointer to the descriptor of the message that should be printed. + */ +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc); + +/** + * @} + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_H__ + + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c new file mode 100644 index 0000000..68c99e3 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c @@ -0,0 +1,163 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser_local.h" + +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + nfc_ndef_record_location_t record_location; + + ret_code_t ret_code; + + uint32_t nfc_data_left = *p_nfc_data_len; + uint32_t temp_nfc_data_len = 0; + + // want to modify -> use local copy + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_parser_memo_desc->p_bin_pay_desc; + nfc_ndef_record_desc_t * p_rec_desc = p_parser_memo_desc->p_rec_desc; + + + while (nfc_data_left > 0) + { + temp_nfc_data_len = nfc_data_left; + + ret_code = ndef_record_parser(p_bin_pay_desc, + p_rec_desc, + &record_location, + p_nfc_data, + &temp_nfc_data_len); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + // verify the records location flags + if (p_parser_memo_desc->p_msg_desc->record_count == 0) + { + if ((record_location != NDEF_FIRST_RECORD) && (record_location != NDEF_LONE_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + if ((record_location != NDEF_MIDDLE_RECORD) && (record_location != NDEF_LAST_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + + ret_code = nfc_ndef_msg_record_add(p_parser_memo_desc->p_msg_desc, p_rec_desc); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + nfc_data_left -= temp_nfc_data_len; + + if ((record_location == NDEF_LAST_RECORD) || (record_location == NDEF_LONE_RECORD)) + { + *p_nfc_data_len = *p_nfc_data_len - nfc_data_left; + return NRF_SUCCESS; + } + else + { + if (p_parser_memo_desc->p_msg_desc->record_count == + p_parser_memo_desc->p_msg_desc->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_nfc_data += temp_nfc_data_len; + p_bin_pay_desc++; + p_rec_desc++; + } + } + + return NRF_ERROR_INVALID_DATA; + +} + + +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc) +{ + + uint32_t max_rec_num; + uint32_t memory_last; + uint8_t * p_end; + nfc_ndef_record_desc_t * * pp_record_desc_array; + + if (*p_result_buf_len < sizeof(parsed_ndef_msg_1_t)) + { + return NRF_ERROR_NO_MEM; + } + + memory_last = (*p_result_buf_len) - sizeof(parsed_ndef_msg_1_t); + max_rec_num = (memory_last / (NFC_PARSER_M_DELTA)) + 1; + + p_parser_memo_desc->p_msg_desc = (nfc_ndef_msg_desc_t *) p_result_buf; + pp_record_desc_array = + (nfc_ndef_record_desc_t * *) &p_parser_memo_desc->p_msg_desc[1]; + p_parser_memo_desc->p_bin_pay_desc = + (nfc_ndef_bin_payload_desc_t *) &pp_record_desc_array[max_rec_num]; + p_parser_memo_desc->p_rec_desc = + (nfc_ndef_record_desc_t *) &p_parser_memo_desc->p_bin_pay_desc[max_rec_num]; + + // initialize message description + p_parser_memo_desc->p_msg_desc->pp_record = pp_record_desc_array; + p_parser_memo_desc->p_msg_desc->max_record_count = max_rec_num; + p_parser_memo_desc->p_msg_desc->record_count = 0; + + p_end = (uint8_t *) &p_parser_memo_desc->p_rec_desc[max_rec_num]; + + *p_result_buf_len = p_end - p_result_buf; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h new file mode 100644 index 0000000..745979c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h @@ -0,0 +1,166 @@ +/** + * 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. + * + */ +#ifndef NFC_NDEF_MSG_PARSER_LOCAL_H__ +#define NFC_NDEF_MSG_PARSER_LOCAL_H__ + +/**@file + * + * @defgroup nfc_ndef_msg_parser_local NDEF message parser (internal) + * @{ + * @ingroup nfc_ndef_msg_parser + * + * @brief Internal part of the parser for NFC NDEF messages. + * + */ + +#include <stdint.h> +#include "nfc_ndef_msg.h" +#include "nfc_ndef_record_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type for holding descriptors that are used by the NDEF parser. + */ +typedef struct +{ + nfc_ndef_msg_desc_t * p_msg_desc; ///< Pointer to the message descriptor. + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc; ///< Pointer to the array of binary payload descriptors. + nfc_ndef_record_desc_t * p_rec_desc; ///< Pointer to the array of record descriptors. +} nfc_ndef_parser_memo_desc_t; + +/** + * @brief Memory allocated for a one-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[1]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[1]; + nfc_ndef_record_desc_t rec_desc[1]; +} parsed_ndef_msg_1_t; + +/** + * @brief Memory allocated for a two-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[2]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[2]; + nfc_ndef_record_desc_t rec_desc[2]; +} parsed_ndef_msg_2_t; + +/** + * @brief Amount of memory that is required per record in addition to the memory allocated for the message descriptor. + */ +#define NFC_PARSER_M_DELTA (sizeof(parsed_ndef_msg_2_t) - sizeof(parsed_ndef_msg_1_t)) + + +/** + * @brief Function for resolving data instances in the provided buffer according + * to requirements of the function @ref internal_ndef_msg_parser. + * + * This internal function distributes the provided memory between certain data instances that are required + * by @ref internal_ndef_msg_parser. + * + * This function should not be used directly. + * + * @param[in] p_result_buf Pointer to the buffer that will be used to allocate + * data instances. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[out] p_parser_memo_desc Pointer to the structure for holding descriptors of the allocated data + * instances. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message. + */ +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc); + + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This internal function parses NDEF messages into certain data instances. + * + * This function should not be used directly. + * + * @param[in,out] p_parser_memo_desc Pointer to the structure that holds descriptors of the allocated data + * instances for the parser. This structure contains the following fields: @n + * .p_msg_desc Pointer to the message descriptor that will + * be filled with parsed data. @n + * .p_bin_pay_desc Pointer to the array of binary payload + * descriptors that will be filled with parsed + * data. @n + * .p_rec_desc Pointer to the array of record descriptors + * that will be filled with parsed data. @n + * The arrays specified by @p .p_bin_pay_desc and @p .p_rec_desc must not + * contain more elements than the message descriptor + * specified by \p .p_msg_desc can hold. + * + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. + * As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + * @retval NRF_ERROR_NO_MEM If the provided memory resources are too small to hold the parsing result. + */ +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_LOCAL_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c new file mode 100644 index 0000000..30376da --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c @@ -0,0 +1,219 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) + +#include <stdint.h> +#include <stdbool.h> +#include "nfc_ndef_record_parser.h" +#include "app_util.h" +#include "nordic_common.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME nfc_ndef_parser +#if NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_RECORD_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_RECORD_PARSER_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_NDEF_RECORD_PARSER_LOG_ENABLED + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in short NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SHORT (2 + NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE) + + +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len) +{ + uint32_t expected_rec_size = NDEF_RECORD_BASE_LONG_SHORT; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->tnf = (nfc_ndef_record_tnf_t) ((*p_nfc_data) & NDEF_RECORD_TNF_MASK); + + /* An NDEF parser that receives an NDEF record with an unknown or unsupported TNF field value + SHOULD treat it as Unknown. See NFCForum-TS-NDEF_1.0 */ + if (p_rec_desc->tnf == TNF_RESERVED) + { + p_rec_desc->tnf = TNF_UNKNOWN_TYPE; + } + + *p_record_location = (nfc_ndef_record_location_t) ((*p_nfc_data) & NDEF_RECORD_LOCATION_MASK); + + uint8_t flags = *(p_nfc_data++); + + p_rec_desc->type_length = *(p_nfc_data++); + + uint32_t payload_lenght; + + if (flags & NDEF_RECORD_SR_MASK) + { + payload_lenght = *(p_nfc_data++); + } + else + { + expected_rec_size += + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE - NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + payload_lenght = uint32_big_decode(p_nfc_data); + p_nfc_data += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + } + + if (flags & NDEF_RECORD_IL_MASK) + { + expected_rec_size += NDEF_RECORD_ID_LEN_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->id_length = *(p_nfc_data++); + } + else + { + p_rec_desc->id_length = 0; + p_rec_desc->p_id = NULL; + } + + expected_rec_size += p_rec_desc->type_length + p_rec_desc->id_length + payload_lenght; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_rec_desc->type_length > 0) + { + p_rec_desc->p_type = p_nfc_data; + + p_nfc_data += p_rec_desc->type_length; + } + else + { + p_rec_desc->p_type = NULL; + } + + if (p_rec_desc->id_length > 0) + { + p_rec_desc->p_id = p_nfc_data; + + p_nfc_data += p_rec_desc->id_length; + } + + if (payload_lenght == 0) + { + p_bin_pay_desc->p_payload = NULL; + } + else + { + p_bin_pay_desc->p_payload = p_nfc_data; + } + + p_bin_pay_desc->payload_length = payload_lenght; + + p_rec_desc->p_payload_descriptor = p_bin_pay_desc; + p_rec_desc->payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy; + + *p_nfc_data_len = expected_rec_size; + + return NRF_SUCCESS; +} + +char const * const tnf_strings[] = +{ + "Empty", + "NFC Forum well-known type", + "Media-type (RFC 2046)", + "Absolute URI (RFC 3986)", + "NFC Forum external type (NFC RTD)", + "Unknown", + "Unchanged", + "Reserved" +}; + +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc) +{ + NRF_LOG_INFO("NDEF record %d content:", num); + NRF_LOG_INFO("TNF: %s",(uint32_t)tnf_strings[p_rec_desc->tnf]); + + if (p_rec_desc->p_id != NULL) + { + NRF_LOG_INFO("ID:"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_id, p_rec_desc->id_length); + } + + if (p_rec_desc->p_type != NULL) + { + NRF_LOG_INFO("type:"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_type, p_rec_desc->type_length); + } + + if (p_rec_desc->payload_constructor == (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_rec_desc->p_payload_descriptor; + + if (p_bin_pay_desc->p_payload != NULL) + { + NRF_LOG_INFO("Payload length: %d bytes", p_bin_pay_desc->payload_length); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_bin_pay_desc->p_payload, p_bin_pay_desc->payload_length); + } + else + { + NRF_LOG_INFO("No payload"); + } + } +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h new file mode 100644 index 0000000..c14a239 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h @@ -0,0 +1,100 @@ +/** + * 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. + * + */ +#ifndef NFC_NDEF_RECORD_PARSER_H__ +#define NFC_NDEF_RECORD_PARSER_H__ + +#include <stdint.h> +#include "sdk_errors.h" +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record_parser Parser for NDEF records + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF records. + * + */ + + +/** + * @brief Function for parsing NDEF records. + * + * This parsing implementation uses the binary payload descriptor (@ref nfc_ndef_bin_payload_desc_t) to describe the payload for the record. + * + * @param[out] p_bin_pay_desc Pointer to the binary payload descriptor that will be filled and referenced by the record descriptor. + * @param[out] p_rec_desc Pointer to the record descriptor that will be filled with parsed data. + * @param[out] p_record_location Pointer to the record location. + * @param[in] p_nfc_data Pointer to the raw data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed record. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected record length is bigger than the provided input data amount. + */ +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of the NDEF record. + * + * @param[in] num Sequence number of the record within the NDEF message. + * @param[in] p_rec_desc Pointer to the descriptor of the record that should be printed. + * + */ +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_PARSER_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c new file mode 100644 index 0000000..c420039 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c @@ -0,0 +1,107 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_TEXT_RECORD) + +#include <string.h> +#include "nfc_text_rec.h" +#include "nrf_error.h" + +#define TEXT_REC_STATUS_SIZE 1 ///< Size of the status. +#define TEXT_REC_STATUS_UTF_POS 7 ///< Position of a character encoding type. +#define TEXT_REC_RESERVED_POS 6 ///< Reserved position. + +const uint8_t nfc_text_rec_type_field[] = {'T'}; + + +/** + * @brief Function for calculating payload size. + */ +__STATIC_INLINE uint32_t nfc_text_rec_payload_size_get(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc) +{ + return (TEXT_REC_STATUS_SIZE + + p_nfc_rec_text_payload_desc->lang_code_len + + p_nfc_rec_text_payload_desc->data_len); +} + +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + if ((p_nfc_rec_text_payload_desc->lang_code_len == 0) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_RESERVED_POS)) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_STATUS_UTF_POS)) + || (p_nfc_rec_text_payload_desc->p_lang_code == NULL) + || (p_nfc_rec_text_payload_desc->data_len == 0) + || (p_nfc_rec_text_payload_desc->p_data == NULL) + || (p_len == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t payload_size = nfc_text_rec_payload_size_get(p_nfc_rec_text_payload_desc); + + if (p_buff != NULL) + { + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff = (p_nfc_rec_text_payload_desc->lang_code_len + + (p_nfc_rec_text_payload_desc->utf << TEXT_REC_STATUS_UTF_POS)); + p_buff += TEXT_REC_STATUS_SIZE; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_lang_code, + p_nfc_rec_text_payload_desc->lang_code_len); + p_buff += p_nfc_rec_text_payload_desc->lang_code_len; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_data, + p_nfc_rec_text_payload_desc->data_len); + } + + *p_len = payload_size; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_TEXT_RECORD) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h new file mode 100644 index 0000000..0e46f89 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h @@ -0,0 +1,161 @@ +/** + * 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 NFC_TEXT_REC_H__ +#define NFC_TEXT_REC_H__ + +/**@file + * + * @defgroup nfc_text_rec Text records + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF Text record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of the Unicode Transformation Format. + * + * Values to specify the type of UTF for an NFC NDEF Text record. + */ +typedef enum +{ + UTF_8 = 0, ///< Unicode Transformation Format 8. + UTF_16 = 1, ///< Unicode Transformation Format 16. +} nfc_text_rec_utf_type_t; + +/** + * @brief Text record payload descriptor. + */ +typedef struct +{ + nfc_text_rec_utf_type_t utf; ///< Type of the Unicode Transformation Format. + + uint8_t const * p_lang_code; ///< Pointer to the IANA language code. + uint8_t lang_code_len; ///< Length of the IANA language code. + + uint8_t const * p_data; ///< Pointer to the user text. + uint32_t data_len; ///< Length of the user text. +} nfc_text_rec_payload_desc_t; + +/** + * @brief Constructor for an NFC NDEF Text record payload. + * + * @param[in] p_nfc_rec_text_payload_desc Pointer to the Text record description. + * @param[out] p_buff Pointer to the payload destination. If NULL, function will + * calculate the expected size of the Text record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. + * Size of the generated record payload as output. + */ +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_text_rec_type_field[]; + +/** + * @brief Size of the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +#define NFC_TEXT_REC_TYPE_LENGTH 1 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for a Text record. + * + * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and + * an instance of type @ref nfc_text_rec_payload_desc_t, which together constitute + * an instance of a Text record. + * + * Use the macro @ref NFC_NDEF_TEXT_RECORD_DESC to access the NDEF Text record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] UTF Unicode Transformation Format. + * @param[in] P_LANG_CODE Pointer to the IANA language code. + * @param[in] LANG_CODE_LEN Length of the IANA language code. + * @param[in] P_DATA Pointer to the user text. + * @param[in] DATA_LEN Length of the user text. + */ +#define NFC_NDEF_TEXT_RECORD_DESC_DEF(NAME, \ + UTF, \ + P_LANG_CODE, \ + LANG_CODE_LEN, \ + P_DATA, \ + DATA_LEN) \ + nfc_text_rec_payload_desc_t NAME##_nfc_text_rec_payload_desc = \ + { \ + .utf = UTF, \ + .p_lang_code = P_LANG_CODE, \ + .lang_code_len = LANG_CODE_LEN, \ + .p_data = P_DATA, \ + .data_len = DATA_LEN, \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_text_rec_type_field, \ + NFC_TEXT_REC_TYPE_LENGTH, \ + nfc_text_rec_payload_constructor, \ + &(NAME##_nfc_text_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Text record descriptor + * instance that was created with @ref NFC_NDEF_TEXT_RECORD_DESC_DEF. + */ +#define NFC_NDEF_TEXT_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_TEXT_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c new file mode 100644 index 0000000..205e585 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c @@ -0,0 +1,72 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_URI_MSG) + +#include <string.h> +#include "nfc_uri_msg.h" +#include "sdk_macros.h" + +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + + /* Create NFC NDEF message description with URI record */ + NFC_NDEF_MSG_DEF(nfc_uri_msg, 1); + NFC_NDEF_URI_RECORD_DESC_DEF(nfc_uri_rec, uri_id_code, p_uri_data, uri_data_len); + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_uri_msg), + &NFC_NDEF_URI_RECORD_DESC(nfc_uri_rec)); + VERIFY_SUCCESS(err_code); + VERIFY_PARAM_NOT_NULL(p_uri_data); + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_uri_msg), + p_buf, + p_len); + + return err_code; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_URI_MSG) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h new file mode 100644 index 0000000..fe95f4f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h @@ -0,0 +1,95 @@ +/** + * 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 NFC_URI_MSG_H__ +#define NFC_URI_MSG_H__ + +/**@file + * + * @defgroup nfc_uri_msg URI messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages with a URI record. + * + */ + +#include "nfc_ndef_msg.h" +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for encoding an NFC NDEF URI message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_NULL If the URI string was invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode. + */ +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_MSG_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c new file mode 100644 index 0000000..f4a60ab --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c @@ -0,0 +1,87 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_URI_REC) + +#include <string.h> +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +const uint8_t ndef_uri_record_type = 'U'; ///< URI Record type. + +/** + * @brief Function for constructing the payload for a URI record. + * + * This function encodes the payload according to the URI record definition. It implements an API + * compatible with @ref p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the URI record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + if (p_buff != NULL) + { + /* Verify if there is enough available memory */ + if (p_input->uri_data_len >= *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Copy descriptor content into the buffer */ + *(p_buff++) = p_input->uri_id_code; + memcpy(p_buff, p_input->p_uri_data, p_input->uri_data_len ); + } + + *p_len = p_input->uri_data_len + 1; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_URI_REC) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h new file mode 100644 index 0000000..163b1c6 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h @@ -0,0 +1,189 @@ +/** + * 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 NFC_URI_REC_H__ +#define NFC_URI_REC_H__ + +/**@file + * + * @defgroup nfc_uri_rec URI records + * @{ + * @ingroup nfc_uri_msg + * + * @brief Generation of NFC NDEF URI record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nfc_uri_id_t + * @brief URI identifier codes according to "URI Record Type Definition" + * (denotation "NFCForum-TS-RTD_URI_1.0" published on 2006-07-24) chapter 3.2.2. + */ +typedef enum +{ + NFC_URI_NONE = 0x00, /**< No prepending is done. */ + NFC_URI_HTTP_WWW = 0x01, /**< "http://www." */ + NFC_URI_HTTPS_WWW = 0x02, /**< "https://www." */ + NFC_URI_HTTP = 0x03, /**< "http:" */ + NFC_URI_HTTPS = 0x04, /**< "https:" */ + NFC_URI_TEL = 0x05, /**< "tel:" */ + NFC_URI_MAILTO = 0x06, /**< "mailto:" */ + NFC_URI_FTP_ANONYMOUS = 0x07, /**< "ftp://anonymous:anonymous@" */ + NFC_URI_FTP_FTP = 0x08, /**< "ftp://ftp." */ + NFC_URI_FTPS = 0x09, /**< "ftps://" */ + NFC_URI_SFTP = 0x0A, /**< "sftp://" */ + NFC_URI_SMB = 0x0B, /**< "smb://" */ + NFC_URI_NFS = 0x0C, /**< "nfs://" */ + NFC_URI_FTP = 0x0D, /**< "ftp://" */ + NFC_URI_DAV = 0x0E, /**< "dav://" */ + NFC_URI_NEWS = 0x0F, /**< "news:" */ + NFC_URI_TELNET = 0x10, /**< "telnet://" */ + NFC_URI_IMAP = 0x11, /**< "imap:" */ + NFC_URI_RTSP = 0x12, /**< "rtsp://" */ + NFC_URI_URN = 0x13, /**< "urn:" */ + NFC_URI_POP = 0x14, /**< "pop:" */ + NFC_URI_SIP = 0x15, /**< "sip:" */ + NFC_URI_SIPS = 0x16, /**< "sips:" */ + NFC_URI_TFTP = 0x17, /**< "tftp:" */ + NFC_URI_BTSPP = 0x18, /**< "btspp://" */ + NFC_URI_BTL2CAP = 0x19, /**< "btl2cap://" */ + NFC_URI_BTGOEP = 0x1A, /**< "btgoep://" */ + NFC_URI_TCPOBEX = 0x1B, /**< "tcpobex://" */ + NFC_URI_IRDAOBEX = 0x1C, /**< "irdaobex://" */ + NFC_URI_FILE = 0x1D, /**< "file://" */ + NFC_URI_URN_EPC_ID = 0x1E, /**< "urn:epc:id:" */ + NFC_URI_URN_EPC_TAG = 0x1F, /**< "urn:epc:tag:" */ + NFC_URI_URN_EPC_PAT = 0x20, /**< "urn:epc:pat:" */ + NFC_URI_URN_EPC_RAW = 0x21, /**< "urn:epc:raw:" */ + NFC_URI_URN_EPC = 0x22, /**< "urn:epc:" */ + NFC_URI_URN_NFC = 0x23, /**< "urn:nfc:" */ + NFC_URI_RFU = 0xFF /**< No prepending is done. Reserved for future use. */ +} nfc_uri_id_t; + + +/** + * @brief Type of description of the payload of a URI record. + */ +typedef struct +{ + nfc_uri_id_t uri_id_code; /**< URI identifier code. */ + uint8_t const * p_uri_data; /**< Pointer to a URI string. */ + uint8_t uri_data_len; /**< Length of the URI string. */ +} uri_payload_desc_t; + +/** + * @brief External reference to the type field of the URI record, defined in the + * file @c nfc_uri_rec.c. It is used in the @ref NFC_NDEF_URI_RECORD_DESC_DEF macro. + */ +extern const uint8_t ndef_uri_record_type; + +/** + * @brief Function for constructing the payload for a URI record. + * + * This function encodes the payload according to the URI record definition. It implements an API + * compatible with @ref p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the URI record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len); + +/** @brief Macro for generating a description of a URI record. + * + * This macro initializes an instance of an NFC NDEF record description of a URI record. + * + * @note The record descriptor is declared as automatic variable, which implies that + * the NDEF message encoding (see @ref nfc_uri_msg_encode) must be done + * in the same variable scope. + * + * @param[in] NAME Name for accessing record descriptor. + * @param[in] URI_ID_CODE URI identifier code that defines the protocol field of the URI. + * @param[in] P_URI_DATA Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] URI_DATA_LEN Length of the URI string. + */ +#define NFC_NDEF_URI_RECORD_DESC_DEF(NAME, \ + URI_ID_CODE, \ + P_URI_DATA, \ + URI_DATA_LEN) \ + uri_payload_desc_t NAME##_ndef_uri_record_payload_desc = \ + { \ + .uri_id_code = (URI_ID_CODE), \ + .p_uri_data = (P_URI_DATA), \ + .uri_data_len = (URI_DATA_LEN) \ + }; \ + \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \ + TNF_WELL_KNOWN, \ + NULL, \ + 0, \ + &ndef_uri_record_type, \ + sizeof(ndef_uri_record_type), \ + nfc_uri_payload_constructor, \ + &NAME##_ndef_uri_record_payload_desc) \ + +/** + * @brief Macro for accessing the NFC NDEF URI record descriptor instance that + * was created with @ref NFC_NDEF_URI_RECORD_DESC_DEF. + */ +#define NFC_NDEF_URI_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_REC_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c new file mode 100644 index 0000000..25c79fb --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c @@ -0,0 +1,1007 @@ +/** + * 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. + * + */ + +#include "sdk_config.h" +#if NFC_T2T_HAL_ENABLED + +#include "hal_nfc_t2t.h" +#include <stdint.h> +#include <stdbool.h> +#include "nfc_t2t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME hal_nfc +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // HAL_NFC_CONFIG_LOG_ENABLED + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit) + * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit) + * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode + * #define NFC_LIB_VERSION 0x03 experimental version intended for support logging module + * #define NFC_LIB_VERSION 0x04 experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit). Removed PCA10036 support. + */ + +#define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ + +#define NFCID1_3RD_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_3RD_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_3RD_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ + +#define NFCID1_SINGLE_SIZE 4u /**< Length of single size NFCID1 */ +#define NFCID1_DOUBLE_SIZE 7u /**< Length of double size NFCID1 */ +#define NFCID1_TRIPLE_SIZE 10u /**< Length of triple size NFCID1 */ +#define NFCID1_DEFAULT_LENGHT NFCID1_DOUBLE_SIZE /**< Length of NFCID1 if user does not provide one */ +#define NFCID1_MAX_LENGHT NFCID1_TRIPLE_SIZE /**< Maximum length of NFCID1 */ + +#define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */ +#define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +#define NRF_NFCT_DEFAULTSTATESLEEP (*(uint32_t volatile *)(0x40005420)) /**< The default state of NFCT. */ +#define NRF_NFCT_DEFAULTSTATESLEEP_MSK 0x1UL /**< Mask for checking the default state of NFCT. */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #define NRF_NFCT_ACTIVATE_CONDS_THR 2 /**< Number of required conditions to activate NFCT. */ + #define NRF_NFCT_ACTIVATE_DELAY 1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); +static void hal_nfc_nfcid1_default_bytes(void); +static void hal_nfc_nfcid1_registers_setup(void); +static void hal_nfc_internal_bytes_setup(void); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ +static uint8_t m_nfcid1_length = 0; /**< Length of NFCID1 provided by user or 0 if not initialized yet */ +static uint8_t m_nfcid1_data[NFCID1_MAX_LENGHT] = {0}; /**< Content of NFCID1 */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +static volatile bool m_nfc_fieldevents_filter_active = false; /**< Flag indicating that field events are ignored. */ +static volatile uint32_t m_nfc_activate_conditions = 0; /**< Number of activation conditions that are met. */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#ifndef HAL_NFC_FIELD_TIMER_PERIOD + #define HAL_NFC_FIELD_TIMER_PERIOD 100 /* unit - us */ +#endif + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +static void hal_nfc_activate_check(void) +{ + static bool is_field_validation_pending = false; + + if (is_field_validation_pending) + { + is_field_validation_pending = false; + m_nfc_fieldevents_filter_active = false; + + // Check the field status with FIELDPRESENT and take action if field is lost. + nrf_nfct_field_event_handler(NFC_FIELD_STATE_UNKNOWN); + return; + } + + m_nfc_activate_conditions++; + if (m_nfc_activate_conditions == NRF_NFCT_ACTIVATE_CONDS_THR) + { + m_nfc_activate_conditions = 0; + + NRF_NFCT->TASKS_ACTIVATE = 1; + is_field_validation_pending = true;; + + // Start the timer second time to validate if tag has locked to the field + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + } +} +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + +static void field_timer_with_callback_config(void) +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos; +#else + NRF_TIMER4->CC[0] = NRF_NFCT_ACTIVATE_DELAY << TIMER_CC_CC_Pos; +#endif + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(TIMER4_IRQn); +} + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + hal_nfc_field_check(); +#else + NRF_TIMER4->TASKS_SHUTDOWN = 1; + hal_nfc_activate_check(); +#endif + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +} + +#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup() +#else +static inline void hal_nfc_common_hw_setup() +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +{ +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + if (type_52840_sample_check()) + { + /* Begin: Bugfix for FTPAN-98 */ + *(volatile uint32_t *) 0x4000568C = 0x00038148; + /* End: Bugfix for FTPAN-98 */ + /* Begin: Bugfix for FTPAN-144 */ + *(volatile uint32_t *) 0x4000561c = 0x01; + *(volatile uint32_t *) 0x4000562c = 0x3F; + *(volatile uint32_t *) 0x4000563c = 0x0; + /* End: Bugfix for FTPAN-144 */ + } +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + // Use Window Grid frame delay mode. + NRF_NFCT->FRAMEDELAYMODE = (NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos) & + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Msk; + + hal_nfc_nfcid1_registers_setup(); +} + +/** @brief Setup NRF_NFCT->NFCID1 and NRF_NFCT->SENSRES registers based on m_nfcid1_data and m_nfcid1_length variables. + */ +static void hal_nfc_nfcid1_registers_setup(void) +{ + uint32_t sens_res_size; // Value that will be written to NRF_NFCT->SENSRES + uint8_t* p_nfcid_remaining_data; // Points to the first byte of m_nfcid1_data remaining to write to NRF_NFCT->NFCID1 registers + + p_nfcid_remaining_data = m_nfcid1_data; + + if (m_nfcid1_length == NFCID1_SINGLE_SIZE) + { + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Single; + } + else + { + if (m_nfcid1_length == NFCID1_DOUBLE_SIZE) + { + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Double; + } + else // then m_nfcid1_length == NFCID1_TRIPLE_SIZE + { + /* MSB of NFCID1_3RD_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_3RD_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_3RD_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_3RD_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_3RD_LAST_BYTE0_SHIFT); + p_nfcid_remaining_data += 3; + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Triple; + } + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + p_nfcid_remaining_data += 3; + } + + NRF_NFCT->NFCID1_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[3] << NFCID1_LAST_BYTE0_SHIFT); + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (sens_res_size << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ +} + +/** @brief Call nfc_t2t_internal_set() with data generated based on m_nfcid1_data and m_nfcid1_length variables. + */ +static void hal_nfc_internal_bytes_setup(void) +{ + if (m_nfcid1_length == NFCID1_TRIPLE_SIZE) + { + (void) nfc_t2t_internal_set(m_nfcid1_data, T2T_INTERNAL_BYTES_NR); + } + else + { + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + if (m_nfcid1_length == NFCID1_DOUBLE_SIZE) + { + // CASCADE TAG send over the air, but not included in internal data + nfc_internal[0] = m_nfcid1_data[0]; // UID0 = Manufacturer ID + nfc_internal[1] = m_nfcid1_data[1]; // UID1 + nfc_internal[2] = m_nfcid1_data[2]; // UID2 + nfc_internal[3] = (uint8_t) CASCADE_TAG_BYTE ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]; // BCC0 = XOR over the 4 previous bytes + nfc_internal[4] = m_nfcid1_data[3]; // UID3 + nfc_internal[5] = m_nfcid1_data[4]; // UID4 + nfc_internal[6] = m_nfcid1_data[5]; // UID5 + nfc_internal[7] = m_nfcid1_data[6]; // UID6 + nfc_internal[8] = nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]; // BCC1 = XOR over the 4 previous bytes + nfc_internal[9] = NFC_LIB_VERSION; // For internal use + } + else // then m_nfcid1_length == NFCID1_SINGLE_SIZE + { + nfc_internal[0] = m_nfcid1_data[0]; // UID0 = Manufacturer ID + nfc_internal[1] = m_nfcid1_data[1]; // UID1 + nfc_internal[2] = m_nfcid1_data[2]; // UID2 + nfc_internal[3] = m_nfcid1_data[3]; // UID3 + nfc_internal[4] = nfc_internal[0] ^ nfc_internal[1] ^ + nfc_internal[2] ^ nfc_internal[3]; // BCC0 = XOR over the 4 previous bytes + memset(&nfc_internal[5], 0xFF, 4); // 4-byte padding + nfc_internal[9] = NFC_LIB_VERSION; // For internal use + } + + (void) nfc_t2t_internal_set(nfc_internal, T2T_INTERNAL_BYTES_NR); + } +} + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + if (m_nfcid1_length == 0) + { + m_nfcid1_length = NFCID1_DEFAULT_LENGHT; + hal_nfc_nfcid1_default_bytes(); + } + + hal_nfc_common_hw_setup(); + hal_nfc_internal_bytes_setup(); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + #if defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + if (!type_52840_sample_check()) + #endif // defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + { + field_timer_with_callback_config(); + } +#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + + NRF_LOG_INFO("Init"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch(event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + if (type_52840_final_check()) + { + hal_nfc_activate_check(); + } + else +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + { + NRF_NFCT->TASKS_ACTIVATE = 1; + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + bool is_first_sample = type_52840_sample_check(); + + if((!is_first_sample) && (m_nfc_fieldevents_filter_active)) + { + return; + } +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch(field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + /* Begin: Bugfix for FTPAN-190 */ + if (!is_first_sample) + { + m_nfc_activate_conditions = 0; + m_nfc_fieldevents_filter_active = true; + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + } + /* END: Bugfix for FTPAN-190 */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + if (is_first_sample) + { + *(volatile uint32_t *)0x40005010 = 1; + } + /* END: Bugfix for FTPAN-116 (IC-12886) */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + +/** @brief Writes default values to m_nfcid1_data based on NRF_FICR->NFC registers. + */ +static void hal_nfc_nfcid1_default_bytes(void) +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2; + + m_nfcid1_data[0] = (uint8_t) LSB_32(nfc_tag_header0 >> 0); + m_nfcid1_data[1] = (uint8_t) LSB_32(nfc_tag_header0 >> 8); + m_nfcid1_data[2] = (uint8_t) LSB_32(nfc_tag_header0 >> 16); + m_nfcid1_data[3] = (uint8_t) LSB_32(nfc_tag_header1 >> 0); + m_nfcid1_data[4] = (uint8_t) LSB_32(nfc_tag_header1 >> 8); + m_nfcid1_data[5] = (uint8_t) LSB_32(nfc_tag_header1 >> 16); + m_nfcid1_data[6] = (uint8_t) LSB_32(nfc_tag_header1 >> 24); + m_nfcid1_data[7] = (uint8_t) LSB_32(nfc_tag_header2 >> 0); + m_nfcid1_data[8] = (uint8_t) LSB_32(nfc_tag_header2 >> 8); + m_nfcid1_data[9] = (uint8_t) LSB_32(nfc_tag_header2 >> 16); +} + + +/** @brief Resets NFCT peripheral to its default state before automatic collision resolution + * procedure. + */ +static inline void nrf_nfct_default_state_reset(void) +{ + if (NRF_NFCT_DEFAULTSTATESLEEP & NRF_NFCT_DEFAULTSTATESLEEP_MSK) // Default state is SLEEP_A + { + NRF_NFCT->TASKS_GOSLEEP = 1; + } + else // Default state is IDLE + { + NRF_NFCT->TASKS_GOIDLE = 1; + } + + /* Disable RX here (will be enabled at SELECTED) */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; +} + + +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + if (id == HAL_NFC_PARAM_ID_NFCID1) + { + if (data_length == 1) + { + uint8_t id_length = *((uint8_t *) p_data); + if (id_length == NFCID1_SINGLE_SIZE || id_length == NFCID1_DOUBLE_SIZE || + id_length == NFCID1_TRIPLE_SIZE) + { + m_nfcid1_length = id_length; + hal_nfc_nfcid1_default_bytes(); + } + else + { + return NRF_ERROR_INVALID_LENGTH; + } + } + else if (data_length == NFCID1_SINGLE_SIZE || data_length == NFCID1_DOUBLE_SIZE || + data_length == NFCID1_TRIPLE_SIZE) + { + m_nfcid1_length = (uint8_t) data_length; + memcpy(m_nfcid1_data, p_data, data_length); + } + else + { + return NRF_ERROR_INVALID_LENGTH; + } + hal_nfc_nfcid1_registers_setup(); + hal_nfc_internal_bytes_setup(); + } + + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + if (id == HAL_NFC_PARAM_ID_NFCID1) + { + if (m_nfcid1_length == 0) + { + m_nfcid1_length = NFCID1_DEFAULT_LENGHT; + hal_nfc_nfcid1_default_bytes(); + } + + if (*p_max_data_length < (size_t) m_nfcid1_length) + { + return NRF_ERROR_DATA_SIZE; + } + + *p_max_data_length = (size_t) m_nfcid1_length; + memcpy(p_data, m_nfcid1_data, m_nfcid1_length); + } + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + NRF_NFCT->TASKS_SENSE = 1; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_LOG_INFO("Start"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + + NRF_LOG_DEBUG("Field detected"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_status = 0; + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + rx_status = (NRF_NFCT->FRAMESTATUS.RX & NRF_NFCT_FRAMESTATUS_RX_MSK); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)", (unsigned int) rx_status); + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + /* Go back to idle state if NFC-A frame with Transmission Errors occurs. */ + if (rx_status) + { + nrf_nfct_default_state_reset(); + } + else + { + /* Look for Tag 2 Type READ Command */ + if (m_nfc_rx_buffer[0] == T2T_READ_CMD) + { + if (m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void*)m_nfc_rx_buffer, + rx_data_size); + } + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + /* No need to parse incoming frames, wait for SELECTED */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; + } + else + { + nrf_nfct_default_state_reset(); + } + } + } + + NRF_LOG_DEBUG("Rx fend"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + NRF_LOG_DEBUG("Selected"); + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("RX: SLP_REQ"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL)) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; +} + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + hal_nfc_common_hw_setup(); + + NRF_LOG_INFO("Reinitialize"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_T2T_HAL_ENABLED diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h new file mode 100644 index 0000000..12b9d93 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h @@ -0,0 +1,203 @@ +/** + * 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 HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t2t_hal NFC Type 2 Tag HAL + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 2 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include <stdint.h> +#include <string.h> +#include <sdk_errors.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is Transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_ID_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size). + To use default NFCID1 of specific length pass one byte containing requested length. + Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be + set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */ + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \<Other event\>: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, maxDataLength will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @note Provided pointer must point to RAM region. + * + * @param[in] p_data Pointer to the memory area in RAM containing data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt new file mode 100644 index 0000000..c64e22b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2015 - 2018, Telit Communications Cyprus Ltd + +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/nfc/t2t_lib/nfc_fixes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h new file mode 100644 index 0000000..1ae29d0 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h @@ -0,0 +1,133 @@ +/** + * 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 NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 Engineering A (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * - 144. NFCT: Not optimal NFC performance + * + * If you are using PCA10056 Engineering B or C (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 190. NFCT: Event FIELDDETECTED may be generated too early. + * + * The use of implemented workarounds for PCA10056 are determined at the runtime and depends + * on the chip variant. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A, B or C + #define HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +#endif + + +/** + * @brief Internal auxiliary function to check if the program is running on NRF52840 chip + * @retval true It is NRF52480 chip + * @retval false It is other chip + */ +static inline bool type_52840_check(void) +{ + return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) && + (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0)); +} + +/** + * @brief Internal auxiliary function to check if the program is running on first sample of + * NRF52840 chip + * @retval true It is NRF52480 chip and it is first sample version + * @retval false It is other chip + */ +static inline bool type_52840_sample_check(void) +{ + return ( type_52840_check() && + ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) && + ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) ); +} + +/** + * @brief Internal auxiliary function to check if the program is running on final version of + * NRF52840 chip + * @retval true It is NRF52480 chip and it is final version + * @retval false It is other chip + */ +static inline bool type_52840_final_check(void) +{ + return ( type_52840_check() && + ( ( ((*(uint32_t *)0xF0000FE8) & 0xF0) != 0x00 ) || + ( ((*(uint32_t *)0xF0000FEC) & 0xF0) != 0x00 ) )); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_FIXES_H__ */ + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h new file mode 100644 index 0000000..cfb88b7 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h @@ -0,0 +1,275 @@ +/** + * Copyright (c) 2015 - 2018, Telit Communications Cyprus Ltd + * + * 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 NFC_T2T_LIB_H__ +#define NFC_T2T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t2t NFC Type 2 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 2 Tag. + * + * @defgroup nfc_t2t_lib NFC tag 2 type emulation library + * @{ + * @ingroup nfc_t2t + * @brief The T2T emulation library interface. + */ + +#include <string.h> +#include <sdk_errors.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_T2T_SIZEOF_INTERNAL_BYTES 10 ///< T2T internal byte size. +#define NFC_T2T_MAX_PAYLOAD_SIZE 988 ///< Maximum NDEF message size. +#define NFC_T2T_MAX_PAYLOAD_SIZE_RAW 1008 ///< No NDEF-TLV and no implicit lock bytes at the end. + +/** @brief Events passed to the callback function. */ +typedef enum +{ + NFC_T2T_EVENT_NONE, + ///< Not used. + + NFC_T2T_EVENT_FIELD_ON, + ///< NFC tag has detected external NFC field and was selected by an NFC polling device. + + NFC_T2T_EVENT_FIELD_OFF, + ///< External NFC field has been removed. + + NFC_T2T_EVENT_DATA_READ, + ///< NFC polling device has read all tag data. + /**< + * Repeated reading in the same session i.e. before @ref NFC_T2T_EVENT_FIELD_OFF event, + * will not trigger another @ref NFC_T2T_EVENT_DATA_READ event. + */ + + NFC_T2T_EVENT_STOPPED + ///< Reference to the application NFC callback has been released using @ref nfc_t2t_done. +} nfc_t2t_event_t; + +typedef enum +{ + NFC_T2T_PARAM_TESTING, ///< Used for unit tests. + NFC_T2T_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size). + To use default NFCID1 of specific length pass one byte containing requested length. + Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be + set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */ +} nfc_t2t_param_id_t; + +/** @brief Callback to pass events from NFC T2T Library to application. + * + * @param[in] p_context Application context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Data to send to the application (event specific). + * @param[in] data_length Length of the data. + */ +typedef void (*nfc_t2t_callback_t)(void * p_context, + nfc_t2t_event_t event, + const uint8_t * p_data, + size_t data_length); + +/** @brief Function for registering the application callback for event signaling. + * + * The callback will be called by NFC T2T Library to notify the application of relevant + * events. It will be called from the HAL_NFC callback context. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS If the application callback was registered successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_setup(nfc_t2t_callback_t callback, void * p_context); + +/** @brief Function for setting an NFC parameter. + * + * @note Not implemented. For future use. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, a wrong data length), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_set(nfc_t2t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Function for querying an NFC parameter value. + * + * @note Not implemented. For future use. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. If the + * buffer is big enough, p_max_data_length will contain the actual size of the + * data. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_get(nfc_t2t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Function for registering the payload to send on reception of a READ request. + * + * The payload is considered to only contain the NDEF message to deliver to a + * reader. The required NDEF TLV will be created implicitly by NFC T2T Library. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If the pointer is not NULL, but the length is zero, the paypload is + * considered to be an empty NDEF message. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @note Provided pointer must point to RAM region. + * + * @param[in] p_payload Pointer to the memory area in RAM containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the raw payload to send on reception of a READ request. + * + * The payload will be delivered directly as-is to the reader, without + * implicitly adding an NDEF TLV container. This can be used if the + * application wants to define the TLVs itself, for example, to provide a different + * memory layout. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload, without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @note Provided pointer must points to RAM region. + * + * @param[in] p_payload Pointer to the memory area in RAM containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_raw_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the sequence of internal bytes. + * + * This refers to the first 10 bytes of the tag memory. The library will set + * a sensible default for these bytes. The application can use this function + * to override the default. + * + * Passing a NULL pointer reverts back to the default sequence. + * The data will be copied by NFC T2T Library, so the memory does not have to remain valid + * after the function returns. + * + * @note When modifying the internal bytes, remember that they must be consistent + * with the NFC hardware register settings (see @ref nfc_t2t_format_internal). + * + * @param[in] p_data Pointer to the memory area containing the data. + * @param[in] data_length Size of the data in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If the data was not NULL and the + * data length was not 10, an error code is returned. + */ +ret_code_t nfc_t2t_internal_set(const uint8_t * p_data, size_t data_length); + +/** @brief Function for activating the NFC frontend. + * + * You must call this function so that events are posted to the application + * callback. + * + * @retval NRF_SUCCESS If the NFC frontend was activated successfully. If the lower layer + * could not be started, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_start(void); + +/** @brief Function for deactivating the NFC frontend. + * + * After calling this function, no more events will be posted to the + * application callback. + * + * @retval NRF_SUCCESS If the NFC frontend was deactivated successfully. If the lower layer + * could not be stopped, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_stop(void); + +/** @brief Function for releasing the reference to the application callback. + * + * After calling this function, the passed callback pointer is no longer + * considered valid. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t nfc_t2t_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif // NFC_T2T_LIB_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a Binary files differnew file mode 100644 index 0000000..c1a7f5a --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a Binary files differnew file mode 100644 index 0000000..f1c00e8 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a Binary files differnew file mode 100644 index 0000000..47c8fa7 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib Binary files differnew file mode 100644 index 0000000..994a76b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c new file mode 100644 index 0000000..fd1477e --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c @@ -0,0 +1,679 @@ +/** + * 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_T2T_PARSER) + +#include <string.h> +#include <stdbool.h> +#include "nrf_delay.h" +#include "nfc_t2t_parser.h" + +#define NRF_LOG_MODULE_NAME nfc_t2t_parser +#if NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T2T_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T2T_PARSER_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_T2T_PARSER_LOG_ENABLED + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for inserting the TLV block into a @ref type_2_tag_t structure. + * + * The content of a TLV block structure pointed by the p_tlv_block is copied into a TLV block + * array within the structure pointed by the p_type_2_tag. + * + * @param[in,out] p_type_2_tag Pointer to the structure that contains the TLV blocks array. + * @param[in] p_tlv_block Pointer to the TLV block to insert. + * + * @retval NRF_SUCCESS If the block was inserted successfully. + * @retval NRF_ERROR_NO_MEM If there is already maximum number of blocks stored in the array. + * + */ +static ret_code_t type_2_tag_tlv_block_insert(type_2_tag_t * p_type_2_tag, + tlv_block_t * p_tlv_block) +{ + if (p_type_2_tag->tlv_count == p_type_2_tag->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_type_2_tag->p_tlv_block_array[p_type_2_tag->tlv_count] = *p_tlv_block; + p_type_2_tag->tlv_count++; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking if the TLV block length is correct. + * + * Some TLV block has predefined length: + * TLV_NULL and TLV_TERMINATOR always have a length of 1 byte. + * TLV_LOCK_CONTROL and TLV_MEMORY_CONTROL always have a length of 3 bytes. + * + * @param[in] p_block_to_check Pointer to the structure that contains the TLV block length. + * + * @retval TRUE If the length is correct. + * @retval FALSE Otherwise. + * + */ +static bool tlv_block_is_data_length_correct(tlv_block_t * p_block_to_check) +{ + switch (p_block_to_check->tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + if (p_block_to_check->length != TLV_NULL_TERMINATOR_LEN) + { + return false; + } + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + if (p_block_to_check->length != TLV_LOCK_MEMORY_CTRL_LEN) + { + return false; + } + break; + + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Any length will do. + break; + } + + return true; +} + +/** + * @brief Function for checking if the end of the tag data area was reached. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset Current byte offset. + * + * @retval TRUE If the offset indicates the end of the data area. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_end_reached(type_2_tag_t * p_type_2_tag, uint16_t offset) +{ + return offset == (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET); +} + + +/** + * @brief Function for checking if version of Type 2 Tag specification read from a tag is supported. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the tag version. + * + * @retval TRUE If the version is supported and tag data can be parsed. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_version_supported(type_2_tag_t * p_type_2_tag) +{ + // Simple check atm, as only 1 major version has been issued so far, so no backward compatibility + // is needed, tags with newer version implemented shall be rejected according to the doc. + return p_type_2_tag->cc.major_version == T2T_SUPPORTED_MAJOR_VERSION; +} + + +/** + * @brief Function for checking if the field fits into the data area specified in + * the Capability Container. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset As Offset of the field to check. + * @param[in] field_length Length of the field to check. + * + * @retval TRUE If the field fits into the data area. + * @retval FALSE If the field exceeds the data area. + * + */ +static bool type_2_tag_is_field_within_data_range(type_2_tag_t * p_type_2_tag, + uint16_t offset, + uint16_t field_length) +{ + // Invalid argument, return false. + if (field_length == 0) + { + return false; + } + return ( (offset + field_length - 1) < + (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET) ) + && ( offset >= T2T_FIRST_DATA_BLOCK_OFFSET ); +} + + +/** + * @brief Function for reading the tag field of a TLV block from the p_raw_data buffer. + * + * This function reads the tag field containing a TLV block type and inserts its value into + * a structure pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_t_offset As input: offset of the tag field to read. As output: offset of + * the first byte after the tag field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the tag type will be + * inserted. + * + * @retval NRF_SUCCESS If the tag field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the tag field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_type_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_t_offset, + tlv_block_t * p_tlv_buf) +{ + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_t_offset, TLV_T_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->tag = p_raw_data[*p_t_offset]; + *p_t_offset += TLV_T_LENGTH; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading the length field of a TLV block from the p_raw_data buffer. + * + * This function reads the length field of a TLV block and inserts its value into a structure + * pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_l_offset As input: offset of the length field to read. As output: offset of + * the first byte after the length field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the length will be + * inserted. + * + * @retval NRF_SUCCESS If the length field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the length field at specified offset exceeds the data + * area specified in the Capability Container or has + * incorrect format. + * + */ +static ret_code_t type_2_tag_length_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_l_offset, + tlv_block_t * p_tlv_buf) +{ + uint16_t length; + + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_SHORT_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = p_raw_data[*p_l_offset]; + + if (length == TLV_L_FORMAT_FLAG) + { + // Check another two bytes. + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_LONG_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = uint16_big_decode(&p_raw_data[*p_l_offset + 1]); + + // Long length value cannot be lower than 0xFF. + if (length < 0xFF) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->length = length; + *p_l_offset += TLV_L_LONG_LENGTH; + + } + else + { + p_tlv_buf->length = length; + *p_l_offset += TLV_L_SHORT_LENGTH; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a pointer to the value field of a TLV block from the p_raw_data buffer. + * + * This function reads a pointer to the value field of a TLV block and inserts it into + * a structure pointed by the p_tlv_buf pointer. If there is no value field present in the + * TLV block, NULL is inserted. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_v_offset As input: offset of the value field to read. As output: offset of + * the first byte after the value field. + * @param[in,out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the value field + * pointer will be inserted. + * + * @retval NRF_SUCCESS If the value field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the value field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_value_ptr_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_v_offset, + tlv_block_t * p_tlv_buf) +{ + if (p_tlv_buf->length == 0) + { + // Clear the value pointer, don't touch the offset. + p_tlv_buf->p_value = NULL; + } + else + { + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_v_offset, p_tlv_buf->length)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->p_value = p_raw_data + *p_v_offset; + *p_v_offset += p_tlv_buf->length; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a single TLV block from the p_raw_data buffer. + * + * This function reads a single TLV block from the p_raw_data buffer and stores its contents in a + * structure pointed by the p_tlv_buf. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to read. As output: offset of the + * next TLV block, 0 if it was the last block. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure that will be filled with + * the data read. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_block_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_offset, + tlv_block_t * p_tlv_buf) +{ + ret_code_t err_code; + memset(p_tlv_buf, 0, sizeof(tlv_block_t)); + + // TLV Tag field. + err_code = type_2_tag_type_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Further processing depends on tag field value. + switch (p_tlv_buf->tag) + { + case TLV_NULL: + // Simply ignore NULL blocks, leave the incremented offset. + break; + + case TLV_TERMINATOR: + // Write 0 to the offset variable, indicating that last TLV block was found. + *p_offset = 0; + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown blocks should also be extracted. + err_code = type_2_tag_length_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_tlv_buf->length > 0) + { + err_code = type_2_tag_value_ptr_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + break; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking the checksum bytes of the UID stored in internal area. + * + * This function calculates the block check character (BCC) bytes based on the parsed serial number + * and compares them with bytes read from the Type 2 Tag. + * + * @param[in] p_sn Pointer to the @ref type_2_tag_serial_number_t structure to check. + * + * @retval TRUE If the calculated BCC matched the BCC from the tag. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_bcc_correct(type_2_tag_serial_number_t * p_sn) +{ + uint8_t bcc1 = (uint8_t)T2T_UID_BCC_CASCADE_BYTE ^ + (uint8_t)p_sn->manufacturer_id ^ + (uint8_t)((p_sn->serial_number_part_1 >> 8) & 0xFF) ^ + (uint8_t)(p_sn->serial_number_part_1 & 0xFF); + + uint8_t bcc2 = (uint8_t)((p_sn->serial_number_part_2 >> 24) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 16) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 8) & 0xFF) ^ + (uint8_t)( p_sn->serial_number_part_2 & 0xFF); + + return (bcc1 == p_sn->check_byte_0) && (bcc2 == p_sn->check_byte_1); +} + + +/** + * @brief Function for parsing an internal area of a Type 2 Tag. + * + * This function reads data from an internal area in the raw data buffer and fills the + * @ref type_2_tag_serial_number_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the internal area succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_internal_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + p_type_2_tag->sn.manufacturer_id = p_raw_data[0]; + p_type_2_tag->sn.serial_number_part_1 = uint16_big_decode(&p_raw_data[1]); + p_type_2_tag->sn.check_byte_0 = p_raw_data[3]; + p_type_2_tag->sn.serial_number_part_2 = uint32_big_decode(&p_raw_data[4]); + p_type_2_tag->sn.check_byte_1 = p_raw_data[8]; + p_type_2_tag->sn.internal = p_raw_data[9]; + + p_type_2_tag->lock_bytes = uint16_big_decode(&p_raw_data[10]); + + if (!type_2_tag_is_bcc_correct(&p_type_2_tag->sn)) + { + NRF_LOG_WARNING("Warning! BCC of the serial number is not correct!"); + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a Capabiliy Container area of a Type 2 Tag. + * + * This function reads data from a Capability Container area in the raw data buffer and fills the + * @ref type_2_tag_capability_container_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the Capability Container succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_cc_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + uint8_t * p_cc_block = p_raw_data + T2T_CC_BLOCK_OFFSET; + + if (p_cc_block[0] != T2T_NFC_FORUM_DEFINED_DATA) + { + return NRF_ERROR_INVALID_DATA; + } + + p_type_2_tag->cc.major_version = MSN_GET(p_cc_block[1]); + p_type_2_tag->cc.minor_version = LSN_GET(p_cc_block[1]); + p_type_2_tag->cc.data_area_size = p_cc_block[2] * 8; + p_type_2_tag->cc.read_access = MSN_GET(p_cc_block[3]); + p_type_2_tag->cc.write_access = LSN_GET(p_cc_block[3]); + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a single TLV block. + * + * This function reads a single TLV block from the raw data buffer, from the position indicated by + * the p_tlv_offset, and adds it to the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to parse. As output: offset of the + * next TLV block, 0 if it was the last block. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_parse(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_tlv_offset) +{ + ret_code_t err_code; + tlv_block_t new_block; + + // Get tag field. + err_code = type_2_tag_tlv_block_extract(p_type_2_tag, p_raw_data, p_tlv_offset, &new_block); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!tlv_block_is_data_length_correct(&new_block)) + { + return NRF_ERROR_INVALID_DATA; + } + + // Further action depends on tag type. + switch (new_block.tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + // Ignore them. + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown tag types are also added. + err_code = type_2_tag_tlv_block_insert(p_type_2_tag, &new_block); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_WARNING("Warning! Not enough memory to insert all of the blocks!"); + return err_code; + } + break; + } + + return NRF_SUCCESS; +} + + +void type_2_tag_clear(type_2_tag_t * p_type_2_tag) +{ + p_type_2_tag->tlv_count = 0; + memset(&p_type_2_tag->cc, 0, sizeof(p_type_2_tag->cc)); + memset(&p_type_2_tag->sn, 0, sizeof(p_type_2_tag->sn)); +} + + +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + ret_code_t err_code; + + type_2_tag_clear(p_type_2_tag); + + err_code = type_2_tag_internal_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = type_2_tag_cc_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!type_2_tag_is_version_supported(p_type_2_tag)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint16_t offset = T2T_FIRST_DATA_BLOCK_OFFSET; + + while (offset > 0) + { + // Check if end of tag is reached (no terminator block was present). + if (type_2_tag_is_end_reached(p_type_2_tag, offset)) + { + NRF_LOG_DEBUG("No terminator block was found in the tag!"); + break; + } + + err_code = type_2_tag_tlv_parse(p_type_2_tag, p_raw_data, &offset); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +void type_2_tag_printout(type_2_tag_t * p_type_2_tag) +{ + uint32_t i; + NRF_LOG_INFO("Type 2 Tag contents:"); + NRF_LOG_INFO("Number of TLV blocks: %d", p_type_2_tag->tlv_count); + + NRF_LOG_DEBUG("Internal data:"); + NRF_LOG_DEBUG(" Manufacturer ID: 0x%02x", p_type_2_tag->sn.manufacturer_id); + NRF_LOG_DEBUG(" Serial number part 1: 0x%04x", p_type_2_tag->sn.serial_number_part_1); + NRF_LOG_DEBUG(" Check byte 0: 0x%02x", p_type_2_tag->sn.check_byte_0); + NRF_LOG_DEBUG(" Serial number part 2: 0x%08lx", p_type_2_tag->sn.serial_number_part_2); + NRF_LOG_DEBUG(" Check byte 1: 0x%02x", p_type_2_tag->sn.check_byte_1); + NRF_LOG_DEBUG(" Internal byte: 0x%02x", p_type_2_tag->sn.internal); + NRF_LOG_DEBUG(" Lock bytes: 0x%04x", p_type_2_tag->lock_bytes); + + NRF_LOG_DEBUG("Capability Container data:"); + NRF_LOG_DEBUG(" Major version number: %d", p_type_2_tag->cc.major_version); + NRF_LOG_DEBUG(" Minor version number: %d", p_type_2_tag->cc.minor_version); + NRF_LOG_DEBUG(" Data area size: %d", p_type_2_tag->cc.data_area_size); + NRF_LOG_DEBUG(" Read access: 0x%02X", p_type_2_tag->cc.read_access); + NRF_LOG_DEBUG(" Write access: 0x%02X", p_type_2_tag->cc.write_access); + + for (i = 0; i < p_type_2_tag->tlv_count; i++) + { + NRF_LOG_INFO("TLV block 0x%02X: ", p_type_2_tag->p_tlv_block_array[i].tag); + switch (p_type_2_tag->p_tlv_block_array[i].tag) + { + case TLV_LOCK_CONTROL: + NRF_LOG_INFO("Lock Control"); + break; + case TLV_MEMORY_CONTROL: + NRF_LOG_INFO("Memory Control"); + break; + case TLV_NDEF_MESSAGE: + NRF_LOG_INFO("NDEF Message"); + break; + case TLV_PROPRIETARY: + NRF_LOG_INFO("Proprietary"); + break; + case TLV_NULL: + NRF_LOG_INFO("Null\r\n"); + break; + case TLV_TERMINATOR: + NRF_LOG_INFO("Terminator"); + break; + default: + NRF_LOG_INFO("Unknown"); + break; + } + + NRF_LOG_INFO(" Data length: %d", p_type_2_tag->p_tlv_block_array[i].length); + + if (p_type_2_tag->p_tlv_block_array[i].length > 0) + { + NRF_LOG_DEBUG(" Data:"); + NRF_LOG_HEXDUMP_DEBUG(p_type_2_tag->p_tlv_block_array[i].p_value, + p_type_2_tag->p_tlv_block_array[i].length); + } + } +} + +#endif // NRF_MODULE_ENABLED(NFC_T2T_PARSER) diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h new file mode 100644 index 0000000..23a8632 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h @@ -0,0 +1,195 @@ +/** + * 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 NFC_TYPE_2_TAG_PARSER_H__ +#define NFC_TYPE_2_TAG_PARSER_H__ + +#include <stdint.h> +#include "nfc_tlv_block.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nfc_type_2_tag Type 2 Tag + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag. + * + */ + +/** + * @brief Descriptor for the internal bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t manufacturer_id; ///< Manufacturer ID (the most significant byte of the UID/serial number). + uint16_t serial_number_part_1; ///< Bytes 5-4 of the tag UID. + uint8_t check_byte_0; ///< First block check character byte (XOR of the cascade tag byte, manufacturer ID byte, and the serial_number_part_1 bytes). + uint32_t serial_number_part_2; ///< Bytes 3-0 of the tag UID. + uint8_t check_byte_1; ///< Second block check character byte (XOR of the serial_number_part_2 bytes). + uint8_t internal; ///< Tag internal bytes. +} type_2_tag_serial_number_t; + +/** + * @brief Descriptor for the Capability Container (CC) bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t major_version; ///< Major version of the supported Type 2 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 2 Tag specification. + uint16_t data_area_size; ///< Size of the data area in bytes. + uint8_t read_access; ///< Read access for the data area. + uint8_t write_access; ///< Write access for the data area. +} type_2_tag_capability_container_t; + +/** + * @brief Type 2 Tag descriptor. + */ +typedef struct +{ + type_2_tag_serial_number_t sn; ///< Values within the serial number area of the tag. + uint16_t lock_bytes; ///< Value of the lock bytes. + type_2_tag_capability_container_t cc; ///< Values within the Capability Container area of the tag. + + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks that can be stored. + tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 2 Tag. + +} type_2_tag_t; + +/** + * @brief Macro for creating and initializing a Type 2 Tag descriptor. + * + * This macro creates and initializes a static instance of a @ref type_2_tag_t structure and + * an array of @ref tlv_block_t descriptors. + * + * Use the macro @ref NFC_TYPE_2_TAG_DESC to access the Type 2 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref tlv_block_t descriptors that can be stored in the array. + * + */ +#define NFC_TYPE_2_TAG_DESC_DEF(NAME, MAX_BLOCKS) \ + static tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static type_2_tag_t NAME##_type_2_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref type_2_tag_t instance that was created + * with @ref NFC_TYPE_2_TAG_DESC_DEF. + */ +#define NFC_TYPE_2_TAG_DESC(NAME) (NAME##_type_2_tag) + + +#define T2T_NFC_FORUM_DEFINED_DATA 0xE1 ///< Value indicating that the Type 2 Tag contains NFC Forum defined data. +#define T2T_UID_BCC_CASCADE_BYTE 0x88 ///< Value used for calculating the first BCC byte of a Type 2 Tag serial number. + +#define T2T_SUPPORTED_MAJOR_VERSION 1 ///< Supported major version of the Type 2 Tag specification. +#define T2T_SUPPORTED_MINOR_VERSION 2 ///< Supported minor version of the Type 2 Tag specification. + +#define T2T_BLOCK_SIZE 4 ///< Type 2 Tag block size in bytes. + +#define T2T_CC_BLOCK_OFFSET 12 ///< Offset of the Capability Container area in the Type 2 Tag. +#define T2T_FIRST_DATA_BLOCK_OFFSET 16 ///< Offset of the data area in the Type 2 Tag. + +/** + * @} + */ + + +/** + * @defgroup nfc_type_2_tag_parser NFC Type 2 Tag parser + * @{ + * @ingroup nfc_t2t + * + * @brief Parser for Type 2 Tag data. + * + */ + +/** + * @brief Function for clearing the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that should be cleared. + * + */ +void type_2_tag_clear(type_2_tag_t * p_type_2_tag); + +/** + * @brief Function for parsing raw data read from a Type 2 Tag. + * + * This function parses the header and the following TLV blocks of a Type 2 Tag. The data is read + * from a buffer and stored in a @ref type_2_tag_t structure. + * + * @param[out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag (should + * point at the first byte of the first block of the tag). + * + * @retval NRF_SUCCESS If the data was parsed successfully. + * @retval NRF_ERROR_NO_MEM If there is not enough memory to store all of the TLV blocks. + * @retval Other If an error occurred during the parsing operation. + * + */ +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data); + +/** + * @brief Function for printing parsed contents of the Type 2 Tag. + * + * @param[in] p_type_2_tag Pointer to the structure that should be printed. + * + */ +void type_2_tag_printout(type_2_tag_t * p_type_2_tag); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TYPE_2_TAG_PARSER_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h new file mode 100644 index 0000000..4c74f36 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h @@ -0,0 +1,102 @@ +/** + * 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 NFC_TLV_BLOCK_H__ +#define NFC_TLV_BLOCK_H__ + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_type_2_tag_tlv_block Type 2 Tag TLV blocks + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag TLV block. + * + */ + +/** + * @brief Tag field values. + * + * Possible values for the tag field in a TLV block. + */ +typedef enum +{ + TLV_NULL = 0x00, ///< Might be used for padding of memory areas. + TLV_LOCK_CONTROL = 0x01, ///< Defines details of the lock bits. + TLV_MEMORY_CONTROL = 0x02, ///< Identifies reserved memory areas. + TLV_NDEF_MESSAGE = 0x03, ///< Contains an NDEF message. + TLV_PROPRIETARY = 0xFD, ///< Tag proprietary information. + TLV_TERMINATOR = 0xFE ///< Last TLV block in the data area. +} tlv_block_types_t; + +/** + * @brief TLV block descriptor. + */ +typedef struct +{ + uint8_t tag; ///< Type of the TLV block. + uint16_t length; ///< Length of the value field. + uint8_t * p_value; ///< Pointer to the value field (NULL if no value field is present in the block). +} tlv_block_t; + +#define TLV_T_LENGTH 1 ///< Length of a tag field. + +#define TLV_L_SHORT_LENGTH 1 ///< Length of a short length field. +#define TLV_L_LONG_LENGTH 3 ///< Length of an extended length field. +#define TLV_L_FORMAT_FLAG 0xFF ///< Value indicating the use of an extended length field. + +#define TLV_NULL_TERMINATOR_LEN 0 ///< Predefined length of the NULL and TERMINATOR TLV blocks. +#define TLV_LOCK_MEMORY_CTRL_LEN 3 ///< Predefined length of the LOCK CONTROL and MEMORY CONTROL blocks. + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TLV_BLOCK_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c new file mode 100644 index 0000000..8495060 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c @@ -0,0 +1,1321 @@ +/** + * 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. + * + */ + +#include "sdk_config.h" +#if NFC_T4T_HAL_ENABLED + +#include "hal_nfc_t4t.h" +#include <stdint.h> +#include <stdbool.h> +#include "nfc_t4t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME hal_nfc +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // HAL_NFC_CONFIG_LOG_ENABLED + + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_DEBUG_PIN_ENABLE + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit) + */ + +#define NFC_LIB_VERSION 0x00u /**< Internal: current NFC lib. version */ + +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ +#define NFCID1_3RD_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_3RD_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_3RD_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_SINGLE_SIZE 4u /**< Length of single size NFCID1 */ +#define NFCID1_DOUBLE_SIZE 7u /**< Length of double size NFCID1 */ +#define NFCID1_TRIPLE_SIZE 10u /**< Length of triple size NFCID1 */ +#define NFCID1_DEFAULT_LENGHT NFCID1_DOUBLE_SIZE /**< Length of NFCID1 if user does not provide one */ +#define NFCID1_MAX_LENGHT NFCID1_TRIPLE_SIZE /**< Maximum length of NFCID1 */ +#define NFC_RX_BUFFER_SIZE 256u /**< NFC Rx data buffer size */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ +#define NFC_T4T_SELRES_PROTOCOL 1u /**< Type 4A Tag PROTOCOL bit setup (b7:b6) for SEL_RES Response frame */ +#define NFC_T4T_SELRES_PROTOCOL_MSK 0x03u /**< PROTOCOL bits mask for SEL_RES Response frame */ + +#ifdef BOARD_PCA10056 + #define NFC_T4T_FWI_MAX 8u /**< Maximum FWI parameter value for 52840*/ +#else + #define NFC_T4T_FWI_MAX 4u /**< Maximum FWI parameter value */ +#endif // BOARD_PCA10056 + +#define NFC_T4T_FWI_52840S_MAX 4u /**< Maximum FWI parameter value for first sample of 52840 */ +#define NFCT_FRAMEDELAYMAX_52840S (0xFFFFUL) /**< Bit mask of FRAMEDELAYMAX field for first sample of 52840 */ +#define NFC_T4T_FWI_DEFAULT 4u /**< Default FWI parameter value */ +#define NRF_T4T_FWI_LISTEN_MAX 8u /**< Maxiumum FWI parameter value in Listen Mode */ +#define NFC_T4T_RATS_CMD 0xE0u /**< RATS Command Byte */ +#define NFC_T4T_RATS_DID_MASK 0x0Fu /**< Mask of DID field inside RATS Parameter Byte. */ +#define NFC_T4T_RATS_DID_RFU 0x0Fu /**< Invalid value of DID - RFU. */ +#define NFC_T4T_S_DESELECT 0xC2u /**< S(DESELECT) Block identifier */ +#define NFC_T4T_S_WTX 0xF2u /**< S(WTX)Block identifier */ +#define NFC_T4T_S_BLOCK_MSK 0xF7u /**< S-Block Mask */ +#define NFC_T4T_I_BLOCK 0x02u /**< I-Block identifier */ +#define NFC_T4T_BLOCK_MSK 0xE6u /**< I/R- block mask (NAD not supported, expect this bit equal 0) */ +#define NFC_T4T_ISO_DEP_MSK 0x02u /**< ISO-DEP block mask */ +#define NFC_T4T_R_BLOCK 0xA2u /**< R- Block identifier (static bits) */ +#define NFC_T4T_WTX_NO_DID_SIZE 0x02 /**< WTX data buffer size without DID field. */ +#define NFC_T4T_WTX_DID_SIZE 0x03 /**< WTX data buffer size with DID field. */ +#define NFC_T4T_WTXM_MAX_VALUE 0x3B /**< WTXM max value, according to 'NFC Forum Digital Protocol Technical Specification 2.0, 16.2.2 */ +#define NFC_T4T_DID_BIT 0x08 /**< Indicates if DID present in ISO-DEP block. */ +#define NFC_T4T_DID_MASK 0x0F /**< DID field mask */ +#define NFCT_INTEN_MSK 0x1C5CFFu /**< Mask for all NFCT interrupts */ + + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +#define NFC_T4T_FWI_TO_FWT(FWI) (256u * 16u * (1 << (FWI))) /**< Macro for calculating FWT (in number of NFC carrier periods) from FWI parameter. */ +#define NFC_T4T_WTXM_MAX(FWI) ( 1 << (NRF_T4T_FWI_LISTEN_MAX - (FWI))) /**< Macro for calculating WTXM based on 'NFC Forum Digital Protocol Specification Version 1.1, Requirement 15.2.2.9', and FRAMEDELAYMAX maximum register setting */ + +/* Begin: Bugfix for FTPAN-xx (AUTOCOLRESCONFIG) */ +#define NRF_NFCT_AUTOCOLRESCONFIG (*(uint32_t volatile *)(0x4000559C)) +#define NRF_NFCT_AUTOCOLRESCONFIG_Pos 0 +/* End: Bugfix for FTPAN-xx */ + +#define NRF_NFCT_DEFAULTSTATESLEEP (*(uint32_t volatile *)(0x40005420)) /**< The default state of NFCT. */ +#define NRF_NFCT_DEFAULTSTATESLEEP_MSK 0x1UL /**< Mask for checking the default state of NFCT. */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #define NRF_NFCT_ACTIVATE_CONDS_THR 2 /**< Number of required conditions to activate NFCT. */ + #define NRF_NFCT_ACTIVATE_DELAY 1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); +static void hal_nfc_nfcid1_default_bytes(void); +static void hal_nfc_nfcid1_registers_setup(void); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ +static volatile uint8_t m_fwi; /**< FWI parameter */ +static volatile uint8_t m_wtxm; /**< WTXM maximum value */ +static volatile uint8_t m_wtx_data[3]; /**< Tx buffer for an S(WTX) block */ +static volatile bool m_deselect = false; /**< Flag indicating reception of DESELECT command */ +static volatile bool m_swtx_sent = false; /**< Flag indicating that SWTX command has been sended. */ +static volatile bool m_pending_msg = false; /**< Flag signaling pending message during SWTX command execution. */ +static volatile const uint8_t * m_pending_msg_ptr = NULL; /**< Pointer to pending message buffer. */ +static volatile size_t m_pending_data_length = 0; /**< Length of pending message data. */ +static volatile bool m_t4t_tx_waiting = false; /**< Indicates if HAL is waiting for upper layer response to received command */ +static volatile uint8_t m_t4t_selres = NFC_T4T_SELRES_PROTOCOL; /**< Protocol bits setup in SEL_RES frame - can be modified using the library API */ +static volatile uint8_t m_did = 0; /**< DID field value. */ +static uint8_t m_nfcid1_length = 0; /**< Length of NFCID1 provided by user or 0 if not initialized yet */ +static uint8_t m_nfcid1_data[NFCID1_MAX_LENGHT] = {0}; /**< Content of NFCID1 */ +static volatile uint8_t m_t4t_active = false; /**< Indicates if NFC Tag is in 4A state (on reception of correct RATS command). */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +static volatile bool m_nfc_fieldevents_filter_active = false; /**< Flag indicating that field events are ignored. */ +static volatile uint32_t m_nfc_activate_conditions = 0; /**< Number of activation conditions that are met. */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +static void hal_nfc_activate_check(void) +{ + static bool is_field_validation_pending = false; + + if (is_field_validation_pending) + { + is_field_validation_pending = false; + m_nfc_fieldevents_filter_active = false; + + // Check the field status with FIELDPRESENT and take action if field is lost. + nrf_nfct_field_event_handler(NFC_FIELD_STATE_UNKNOWN); + return; + } + + m_nfc_activate_conditions++; + if (m_nfc_activate_conditions == NRF_NFCT_ACTIVATE_CONDS_THR) + { + m_nfc_activate_conditions = 0; + + NRF_NFCT->TASKS_ACTIVATE = 1; + is_field_validation_pending = true; + + // Start the timer second time to validate if tag has locked to the field + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + } +} +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + +static void field_timer_with_callback_config(void) +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos; +#else + NRF_TIMER4->CC[0] = NRF_NFCT_ACTIVATE_DELAY << TIMER_CC_CC_Pos; +#endif + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(TIMER4_IRQn); +} + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + hal_nfc_field_check(); +#else + NRF_TIMER4->TASKS_SHUTDOWN = 1; + hal_nfc_activate_check(); +#endif + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +} + +#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup() +#else +static inline void hal_nfc_common_hw_setup() +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +{ +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + if (type_52840_sample_check()) + { + /* Begin: Bugfix for FTPAN-98 */ + *(volatile uint32_t *) 0x4000568C = 0x00038148; + /* End: Bugfix for FTPAN-98 */ + /* Begin: Bugfix for FTPAN-144 */ + *(volatile uint32_t *) 0x4000561c = 0x01; + *(volatile uint32_t *) 0x4000562c = 0x3F; + *(volatile uint32_t *) 0x4000563c = 0x0; + /* End: Bugfix for FTPAN-144 */ + } +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + +/* Begin: Bugfix for FTPAN-17 */ +/* fixed by avoiding usage of FIELDLOST event */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/* End: Bugfix for FTPAN-17 */ + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + hal_nfc_nfcid1_registers_setup(); + + /* Set FRAMEDELAYMAX to default setting */ + uint8_t fwi = NFC_T4T_FWI_DEFAULT; + + ret_code_t err_code = hal_nfc_parameter_set( HAL_NFC_PARAM_FWI, &fwi, sizeof(fwi)); + ASSERT(err_code == NRF_SUCCESS); + + /* Set PROTOCOL bits for Type 4A Tag */ + NRF_NFCT->SELRES = + (m_t4t_selres << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; +} + +/** @brief Setup NRF_NFCT->NFCID1 and NRF_NFCT->SENSRES registers based on m_nfcid1_data and m_nfcid1_length variables. + */ +static void hal_nfc_nfcid1_registers_setup(void) +{ + uint32_t sens_res_size; // Value that will be written to NRF_NFCT->SENSRES + uint8_t* p_nfcid_remaining_data; // Points to the first byte of m_nfcid1_data remaining to write to NRF_NFCT->NFCID1 registers + + p_nfcid_remaining_data = m_nfcid1_data; + + if (m_nfcid1_length == NFCID1_SINGLE_SIZE) + { + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Single; + } + else + { + if (m_nfcid1_length == NFCID1_DOUBLE_SIZE) + { + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Double; + } + else // then m_nfcid1_length == NFCID1_TRIPLE_SIZE + { + /* MSB of NFCID1_3RD_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_3RD_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_3RD_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_3RD_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_3RD_LAST_BYTE0_SHIFT); + p_nfcid_remaining_data += 3; + sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Triple; + } + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + p_nfcid_remaining_data += 3; + } + + NRF_NFCT->NFCID1_LAST = + ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) p_nfcid_remaining_data[3] << NFCID1_LAST_BYTE0_SHIFT); + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (sens_res_size << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ + + m_t4t_active = false; + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; +} + + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + if (m_nfcid1_length == 0) + { + m_nfcid1_length = NFCID1_DEFAULT_LENGHT; + hal_nfc_nfcid1_default_bytes(); + } + + hal_nfc_common_hw_setup(); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + #if defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + if (!type_52840_sample_check()) + #endif // defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + { + field_timer_with_callback_config(); + } +#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND) + + NRF_LOG_INFO("Init"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch (event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + if (type_52840_final_check()) + { + hal_nfc_activate_check(); + } + else +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + { + NRF_NFCT->TASKS_ACTIVATE = 1; + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + bool is_first_sample = type_52840_sample_check(); + + if((!is_first_sample) && (m_nfc_fieldevents_filter_active)) + { + return; + } +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch (field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + /* Begin: Bugfix for FTPAN-190 */ + if (!is_first_sample) + { + m_nfc_activate_conditions = 0; + m_nfc_fieldevents_filter_active = true; + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + } + /* END: Bugfix for FTPAN-190 */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + if (is_first_sample) + { + *(volatile uint32_t *)0x40005010 = 1; + } + /* END: Bugfix for FTPAN-116 (IC-12886) */ +#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + m_t4t_active = false; + + /* Go back to default frame delay mode, bugfix for tag locking. */ + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +__STATIC_INLINE void hal_nfc_wtx_data_set(bool did_present) +{ + uint32_t wtx_data_size; + + m_wtx_data[0] = NFC_T4T_S_WTX; + if (did_present) + { + m_wtx_data[0] |= NFC_T4T_DID_BIT; + m_wtx_data[1] = m_did; + m_wtx_data[2] = m_wtxm; + wtx_data_size = NFC_T4T_WTX_DID_SIZE; + } + else + { + m_wtx_data[1] = m_wtxm; + wtx_data_size = NFC_T4T_WTX_NO_DID_SIZE; + } + + NRF_NFCT->PACKETPTR = (uint32_t) m_wtx_data; + NRF_NFCT->TXD.AMOUNT = (wtx_data_size << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_ExactVal << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + m_t4t_tx_waiting = true; +} + + +/** @brief Writes default values to m_nfcid1_data based on NRF_FICR->NFC registers. + */ +static void hal_nfc_nfcid1_default_bytes(void) +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2; + + m_nfcid1_data[0] = (uint8_t) LSB_32(nfc_tag_header0 >> 0); + m_nfcid1_data[1] = (uint8_t) LSB_32(nfc_tag_header0 >> 8); + m_nfcid1_data[2] = (uint8_t) LSB_32(nfc_tag_header0 >> 16); + m_nfcid1_data[3] = (uint8_t) LSB_32(nfc_tag_header1 >> 0); + m_nfcid1_data[4] = (uint8_t) LSB_32(nfc_tag_header1 >> 8); + m_nfcid1_data[5] = (uint8_t) LSB_32(nfc_tag_header1 >> 16); + m_nfcid1_data[6] = (uint8_t) LSB_32(nfc_tag_header1 >> 24); + m_nfcid1_data[7] = (uint8_t) LSB_32(nfc_tag_header2 >> 0); + m_nfcid1_data[8] = (uint8_t) LSB_32(nfc_tag_header2 >> 8); + m_nfcid1_data[9] = (uint8_t) LSB_32(nfc_tag_header2 >> 16); +} + + +/** @brief Resets NFCT peripheral to its default state before automatic collision resolution + * procedure. + */ +static inline void nrf_nfct_default_state_reset(void) +{ + if (NRF_NFCT_DEFAULTSTATESLEEP & NRF_NFCT_DEFAULTSTATESLEEP_MSK) // Default state is SLEEP_A + { + NRF_NFCT->TASKS_GOSLEEP = 1; + } + else // Default state is IDLE + { + NRF_NFCT->TASKS_GOIDLE = 1; + } + + /* Disable RX here (will be enabled at SELECTED) */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; +} + + +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + /* Parameter validation is done in upper-layer */ + + if (id == HAL_NFC_PARAM_FWI) + { + /* Update Frame Wait Time setting; possible settings are limited by NFCT hardware */ + m_fwi = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + /* Frame Wait Time settings for first sample of 52840 */ + if (type_52840_sample_check()) + { + if (m_fwi > NFC_T4T_FWI_52840S_MAX) + { + return NRF_ERROR_INVALID_PARAM; + } + /* Set FRAMEDELAYTIME */ + if (m_fwi == NFC_T4T_FWI_52840S_MAX) + { + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_52840S; + } + else + { + NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi); + } + } + else + { + if (m_fwi > NFC_T4T_FWI_MAX) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* Set FRAMEDELAYTIME */ + if (m_fwi == NFC_T4T_FWI_MAX) + { + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk; + } + else + { + NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi); + } + } + + if (NFC_T4T_WTXM_MAX(m_fwi) > NFC_T4T_WTXM_MAX_VALUE) + { + m_wtxm = NFC_T4T_WTXM_MAX_VALUE; + } + else + { + m_wtxm = NFC_T4T_WTXM_MAX(m_fwi); + } + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Update SEL_RES 'Protocol' bits setting */ + uint8_t sel_res = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + if (sel_res > NFC_T4T_SELRES_PROTOCOL_MSK) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_t4t_selres = sel_res; + NRF_NFCT->SELRES = + (m_t4t_selres << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + } + else if (id == HAL_NFC_PARAM_DID) + { + if (data_length > sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + + m_did = (data_length == sizeof(m_did)) ? *((uint8_t *)p_data) : 0; + } + else if (id == HAL_NFC_PARAM_NFCID1) + { + if (data_length == 1) + { + uint8_t id_length = *((uint8_t *) p_data); + if (id_length == NFCID1_SINGLE_SIZE || id_length == NFCID1_DOUBLE_SIZE || + id_length == NFCID1_TRIPLE_SIZE) + { + m_nfcid1_length = id_length; + hal_nfc_nfcid1_default_bytes(); + } + else + { + return NRF_ERROR_INVALID_LENGTH; + } + } + else if (data_length == NFCID1_SINGLE_SIZE || data_length == NFCID1_DOUBLE_SIZE || + data_length == NFCID1_TRIPLE_SIZE) + { + m_nfcid1_length = (uint8_t) data_length; + memcpy(m_nfcid1_data, p_data, data_length); + } + else + { + return NRF_ERROR_INVALID_LENGTH; + } + hal_nfc_nfcid1_registers_setup(); + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + if (*p_max_data_length < 1) + { + *p_max_data_length = 1; + return NRF_ERROR_DATA_SIZE; + } + + if (id == HAL_NFC_PARAM_FWI) + { + *((uint8_t *) p_data) = m_fwi; + *p_max_data_length = sizeof(m_fwi); + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Get SEL_RES 'Protocol' bits setting */ + *((uint8_t *) p_data) = m_t4t_selres; + *p_max_data_length = sizeof(m_t4t_selres); + } + else if (id == HAL_NFC_PARAM_DID) + { + *((uint8_t *) p_data) = m_did; + *p_max_data_length = sizeof(m_did); + } + else if (id == HAL_NFC_PARAM_NFCID1) + { + if (m_nfcid1_length == 0) + { + m_nfcid1_length = NFCID1_DEFAULT_LENGHT; + hal_nfc_nfcid1_default_bytes(); + } + + if (*p_max_data_length < (size_t) m_nfcid1_length) + { + return NRF_ERROR_DATA_SIZE; + } + + *p_max_data_length = (size_t) m_nfcid1_length; + memcpy(p_data, m_nfcid1_data, m_nfcid1_length); + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + NRF_NFCT->TASKS_SENSE = 1; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_LOG_INFO("Start"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + if(m_swtx_sent) + { + m_pending_msg_ptr = p_data; + m_pending_data_length = data_length; + m_pending_msg = true; + + NRF_LOG_DEBUG("Pending message."); + return NRF_SUCCESS; + } + + m_t4t_tx_waiting = false; + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); //Moved to the end in T4T to avoid delaying TASKS_STARTX + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + + NRF_LOG_DEBUG("Field detected"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_status = 0; + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + rx_status = (NRF_NFCT->FRAMESTATUS.RX & NRF_NFCT_FRAMESTATUS_RX_MSK); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)", (unsigned int) rx_status); + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + /* Ignore all NFC-A data frames with Transmission Error */ + if (rx_status) + { + /* Go back to idle state if currently in the ACTIVE_A state */ + if (!m_t4t_active) + { + nrf_nfct_default_state_reset(); + } + /* Stay in the CARD_EMULATOR_4A state */ + else + { + /* Command with Transmission Error, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + } + else + { + /* Look for NFC-A Commands */ + if (!m_t4t_active) + { + // 'NFC Forum Digital Protocol Technical Specification 2.0, 14.6.1.13' */ + if ((m_nfc_rx_buffer[0] == NFC_T4T_RATS_CMD) && + ((m_nfc_rx_buffer[1] & NFC_T4T_RATS_DID_MASK) != NFC_T4T_RATS_DID_RFU)) + { + /* Disable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG | + (1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + m_t4t_active = true; + NRF_LOG_DEBUG("RX: T4T Activate"); + } + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + else if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + // disable RX here (will enable at SELECTED) + m_slp_req_received = true; + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos; + } + else + { + nrf_nfct_default_state_reset(); + } + } + /* Look for Tag 4 Type Commands */ + else + { + bool did_present; + uint8_t did; + + did_present = (m_nfc_rx_buffer[0] & NFC_T4T_DID_BIT) != 0; + did = m_did; + + // React only to the ISO-DEP blocks that are directed to our tag. + if ((!did_present) && (did > 0)) // 'NFC Forum Digital Protocol Technical Specification 2.0, 16.1.2.12' */ + { + /* Not our ISO-DEP block, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + else if ((!did_present) || (did == (m_nfc_rx_buffer[1] & NFC_T4T_DID_MASK))) + { + if ((m_nfc_rx_buffer[0] & NFC_T4T_S_BLOCK_MSK) == NFC_T4T_S_DESELECT) + { + m_deselect = true; + NRF_LOG_DEBUG("RX: T4T Deselect"); + } + else if (m_swtx_sent && ((m_nfc_rx_buffer[0] & NFC_T4T_S_BLOCK_MSK) == NFC_T4T_S_WTX)) + { + m_swtx_sent = false; + + NRF_LOG_DEBUG("RX: S(WTX) response"); + + if (m_pending_msg) + { + m_pending_msg = false; + + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << + NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr; + NRF_NFCT->TXD.AMOUNT = (m_pending_data_length << + NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + m_t4t_tx_waiting = false; + NRF_LOG_DEBUG("Sending pending message!"); + } + else + { + hal_nfc_wtx_data_set(did_present); + } + } + else if ((m_nfc_rx_buffer[0] & NFC_T4T_BLOCK_MSK) == NFC_T4T_I_BLOCK) + { + /* Set up default transmission of S(WTX) block. Tx will be executed only if FDT timer + * expires (FrameDelayMode-ExactVal) before hal_nfc_send is called */ + hal_nfc_wtx_data_set(did_present); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << + NFCT_INTENSET_TXFRAMEEND_Pos); + } + else + { + /* Not a valid ISO-DEP block, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + } + else + { + /* Not our ISO-DEP block, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + } + + if (m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void *)m_nfc_rx_buffer, + rx_data_size); + } + /* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + } + NRF_LOG_DEBUG("Rx fend"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + if (m_deselect) + { + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + NRF_NFCT->TASKS_GOSLEEP = 1; + /* Disable RX here (will be enabled at SELECTED) */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; + m_deselect = false; + m_t4t_active = false; + } + else + { + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + NRF_NFCT->INTENSET = + (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + } + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + m_t4t_active = false; + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; + + NRF_LOG_DEBUG("Selected"); + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("RX: SLP_REQ"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + if (NRF_NFCT->EVENTS_TXFRAMESTART && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMESTART_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + + if (m_t4t_tx_waiting) + { + m_t4t_tx_waiting = false; + m_swtx_sent = true; + + NRF_LOG_DEBUG("Response timeout, sending WTX!"); + } + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; +} + + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + hal_nfc_common_hw_setup(); + + NRF_LOG_INFO("Reinitialize"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_T4T_HAL_ENABLED diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h new file mode 100644 index 0000000..4ffc9e1 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h @@ -0,0 +1,203 @@ +/** + * 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. + * + */ + +#ifndef HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t4t_hal NFC Type 4 Tag HAL + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 4 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include <stdint.h> +#include <string.h> +#include <sdk_errors.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for the set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_FWI, ///< Frame Wait Time parameter. + HAL_NFC_PARAM_SELRES, ///< Parameter for setting the 'Protocol' bits for SEL_RES packet. + HAL_NFC_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (simple, double, or triple size). + To use default NFCID1 of specific length pass one byte containing requested length. + Default 7-byte NFCID1 will be used if this parameter was not set before nfc_t4t_setup(). */ + HAL_NFC_PARAM_DID, ///< Parameter for DID field management. + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \<Other event\>: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in, out] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @param[in] p_data The data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt new file mode 100644 index 0000000..1e65dd2 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2016 - 2018, Telit Communications Cyprus Ltd + +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/nfc/t4t_lib/nfc_fixes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h new file mode 100644 index 0000000..e39e14f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h @@ -0,0 +1,132 @@ +/** + * 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 NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 Engineering A (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * - 144. NFCT: Not optimal NFC performance + * + * If you are using PCA10056 Engineering B or C (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 190. NFCT: Event FIELDDETECTED may be generated too early. + * + * The use of implemented workarounds for PCA10056 are determined at the runtime and depends + * on the chip variant. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A, B or C + #define HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND +#endif + +/** + * @brief Internal auxiliary function to check if the program is running on NRF52840 chip + * @retval true It is NRF52480 chip + * @retval false It is other chip + */ +static inline bool type_52840_check(void) +{ + return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) && + (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0)); +} + +/** + * @brief Internal auxiliary function to check if the program is running on first sample of + * NRF52840 chip + * @retval true It is NRF52480 chip and it is first sample version + * @retval false It is other chip + */ +static inline bool type_52840_sample_check(void) +{ + return ( type_52840_check() && + ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) && + ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) ); +} + +/** + * @brief Internal auxiliary function to check if the program is running on final version of + * NRF52840 chip + * @retval true It is NRF52480 chip and it is final version + * @retval false It is other chip + */ +static inline bool type_52840_final_check(void) +{ + return ( type_52840_check() && + ( ( ((*(uint32_t *)0xF0000FE8) & 0xF0) != 0x00 ) || + ( ((*(uint32_t *)0xF0000FEC) & 0xF0) != 0x00 ) )); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_FIXES_H__ */ + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h new file mode 100644 index 0000000..1ca3ca1 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h @@ -0,0 +1,323 @@ +/** + * Copyright (c) 2016 - 2018, Telit Communications Cyprus Ltd + * + * 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 NFC_T4T_LIB_H__ +#define NFC_T4T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t4t NFC Type 4 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 4 Tag. + * + * @defgroup nfc_t4t_lib NFC tag 4 type emulation library + * @{ + * @ingroup nfc_t4t + * @brief The T4T emulation library interface + * + * This is the NFC Forum NDEF tag 4 type emulation library. It implements the ISO14443-4A protocol + * (ISO-DEP) and additionally can emulate a read-writable NDEF content. If the emulation of the NDEF + * content is not needed, the library works in a raw mode where all APDUs are delivered to the user, + * who is then responsible to generate a timely RPDU as a response. + * + * The sequence of initializing functions determines whether the NDEF emulation will run or whether + * the raw mode is used. + * + * - E.g. NDEF emulation + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_ndef_rwpayload_set or @ref nfc_t4t_ndef_staticpayload_set + * * @ref nfc_t4t_emulation_start + * * ... running in NDEF emulation mode ... + * - E.g. RAW mode + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_emulation_start + * * ... running in RAW emulation mode ... + */ + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NFC_T4T_MAX_PAYLOAD_SIZE 0xFFF0U + +/**< @brief Emulation mode. */ +typedef enum +{ + NFC_T4T_EMUMODE_NDEF, ///< Emulated NDEF AID and EF-Files. + NFC_T4T_EMUMODE_PICC ///< Run just ISO-DEP, deliver I-Frames up. +} nfc_t4t_emu_mode_t; + + +/**< @brief Event identifiers used by the @ref nfc_t4t_callback_t */ +typedef enum +{ + NFC_T4T_EVENT_NONE, + ///< This ID is never used. Dummy value for completeness. + + NFC_T4T_EVENT_FIELD_ON, + ///< External Reader polling detected. + + NFC_T4T_EVENT_FIELD_OFF, + ///< External Reader polling ended. + + NFC_T4T_EVENT_NDEF_READ, + ///< External Reader has read static NDEF-Data from Emulation. + /**< + * A Read operation happened on last byte of NDEF-Data. + */ + + NFC_T4T_EVENT_NDEF_UPDATED, + ///< External Reader has written to length information of NDEF-Data from Emulation. + /**< + * The usual behavior of a Reader-Writer that accesses NDEF information for update is to set + * the length to zero at the beginning of the update process. It then writes the content + * of NDEF-Data. When all content is written it will update the length information inside + * the NDEF file. This event will be generated every time an update to the length is happening. + * This length information is residing in the first 2 bytes of the NDEF-Content container and is called 'NLEN'. + * Since this callback is triggered on any access to these bytes the returned data_length + * information might not be consistent (e.g. in case of only a single byte write to the length). + * + * @param[out] data_length Current value of NDEF content length + * information i.e. 'NLEN' field. + */ + + NFC_T4T_EVENT_DATA_TRANSMITTED, + ///< In Raw mode it signals that the data from @ref nfc_t4t_response_pdu_send have been sent out. + + NFC_T4T_EVENT_DATA_IND, + ///< In Raw mode delivers the APDU fragments + /**< + * All @ref NFC_T4T_EVENT_DATA_IND events that have the @ref NFC_T4T_DI_FLAG_MORE flag set + * belong to the same APDU. The first @ref NFC_T4T_EVENT_DATA_IND without @ref NFC_T4T_DI_FLAG_MORE + * flag signals the completeness of the APDU. The Application then has to reply with a call + * to @ref nfc_t4t_response_pdu_send. The library will handle internally the fragmentation of + * the response towards the Reader-Writer. The data of the response PDU must be kept + * valid until the next callback from the library happens (e.g. next @ref NFC_T4T_EVENT_DATA_IND + * or @ref NFC_T4T_EVENT_FIELD_OFF). + * + * @param[out] p_data Pointer to the fragment of APDU. + * @param[out] data_length Length of data. + * @param[out] flags @ref nfc_t4t_data_ind_flags_t. + */ +} nfc_t4t_event_t; + +/**< @brief Flags coming with nfc_t4t_callback_t at @ref NFC_T4T_EVENT_DATA_IND event.*/ +typedef enum +{ + NFC_T4T_DI_FLAG_NONE = 0x00, ///< Dummy value. + NFC_T4T_DI_FLAG_MORE = 0x01 ///< This signals that more data is expected to be received. +} nfc_t4t_data_ind_flags_t; + +/**< @brief Parameter IDs that can be set/get with @ref nfc_t4t_parameter_set or + * @ref nfc_t4t_parameter_get. + */ +typedef enum +{ + NFC_T4T_PARAM_TESTING, ///< Internal usage only for Unit-Testing. + NFC_T4T_PARAM_FWI, ///< Frame Wait Time parameter + NFC_T4T_PARAM_SELRES, ///< Parameter for setting 'Protocol' bits for SEL_RES packet + NFC_T4T_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size). + To use default NFCID1 of specific length pass one byte containing requested length. + Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be + set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */ +} nfc_t4t_param_id_t; + +/** @brief Callback to pass events from NFCLib to application. + * + * @param[out] p_context Application context for callback execution. + * @param[out] event The event that occurred. see @ref nfc_t4t_event_t. + * @param[out] p_data Data to send to the application (event specific). + * @param[out] data_length Length of the data. In case of @ref NFC_T4T_EVENT_NDEF_UPDATED, this parameter + * contains the value of the 'NLEN' field of the NDEF File; + * if the value is non-zero, it corresponds to the new size of the NDEF Message in the updated NDEF File. + * @param[out] flags Some events deliver flags. see @ref nfc_t4t_event_t for details. + */ +typedef void (*nfc_t4t_callback_t)(void * p_context, + nfc_t4t_event_t event, + const uint8_t * p_data, + size_t data_length, + uint32_t flags); + +/** @brief Register the application callback for event signaling. + * + * The callback will be called by NFCLib to notify the application of relevant events. It will be + * called from the HAL_NFC callback context. The library support 3 different Modes of Emulation: + * - Raw ISO-Dep exchanges. All PDUs are signaled through the callback. + * - Read-Only T4T NDEF-Tag. A static buffer is served. Only Field-Status callbacks. + * - Read-Write T4T NDEF-Tag. A mutable buffer is used. Only Field-Status callbacks. + * + * The default mode is Raw ISO-Dep mode. The two other NDEF T4T modes are activated through + * the corresponding @ref nfc_t4t_ndef_rwpayload_set/ @ref nfc_t4t_ndef_staticpayload_set functions. + * The mode is locked in with a call to @ref nfc_t4t_emulation_start. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_setup(nfc_t4t_callback_t callback, void * p_context); + +/** @brief Set emulation buffer and content for a NDEF Tag emulation that is Read/Writable. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * If an external Reader-Writer changes the NDEF content it is signaled through the app-callback. + * + * @param[in] p_emulation_buffer Buffer pointer + * @param[in] buffer_length Length of buffer (maximum writable NDEF size) + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_ndef_rwpayload_set(uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Set emulationBuffer and Content for a NDEF Tag emulation that is Read-Only. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * Since no write access is done to the buffer, the content could reside in flash memory. + * + * @param[in] p_emulation_buffer Const buffer pointer + * @param[in] buffer_length Length of contained NDEF payload message + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running stated. + */ +ret_code_t nfc_t4t_ndef_staticpayload_set(const uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Send a raw response PDU after getting a Request PDU callback. + * + * When the library works in raw ISO-DEP mode it will signal request PDUs through the callback. + * The application then has to answer with a response PDU. It will use this function to send back + * the response PDU. This function can not be used in T4T NDEF (RW / STATIC) emulation modes. + * + * The lower ISODEP layer will handle the defragmentation of a long response PDU into smaller + * pieces that the PCD can understand. + * + * @param[in] p_pdu Const PDU pointer. + * @param[in] pdu_length Length of PDU. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running state. + */ +ret_code_t nfc_t4t_response_pdu_send(const uint8_t * p_pdu, size_t pdu_length); + +/** @brief Set an NFC parameter. + * + * Allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_set(nfc_t4t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Query an NFC parameter value. + * + * The queried value will be placed into the passed data buffer. + * If the buffer is too small, p_max_data_length will contain the required buffer size. + * If the buffer is big enough, p_max_data_length will contain the actual size of the data. + * + * @param[in] id ID of the parameter to query. + * @param[out] p_data Pointer to a buffer receiving the queried data. + * @param[out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_get(nfc_t4t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Activate the NFC frontend. + * + * Only after calling this function, events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Already started. + */ +ret_code_t nfc_t4t_emulation_start(void); + +/** + * @brief Deactivate the NFC frontend. + * + * After calling this function, no more events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Emulation was already stopped + */ +ret_code_t nfc_t4t_emulation_stop(void); + +/** + * @brief Release reference to application callback. + * + * After calling this function, the passed callback pointer is no longer considered valid. + * After calling this function, the passed p_ndef pointer is no longer considered valid. + * + * You need to restart with @ref nfc_t4t_setup to run a new Emulation. + * + * @retval NRF_SUCCESS Always succeeds. + */ +ret_code_t nfc_t4t_done(void); + +#ifdef __cplusplus +} +#endif + +/** + @} +*/ + +#endif // NFC_T4T_LIB_H__ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a Binary files differnew file mode 100644 index 0000000..606ca46 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a Binary files differnew file mode 100644 index 0000000..68ec393 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a Binary files differnew file mode 100644 index 0000000..cfc9aaf --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib Binary files differnew file mode 100644 index 0000000..e97272b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c new file mode 100644 index 0000000..71e5155 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c @@ -0,0 +1,261 @@ +/** + * 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_APDU_ENABLED + +#include "nfc_t4t_apdu.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME nfc_t4t_apdu +#if NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_APDU_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_APDU_LOG_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_T4T_APDU_LOG_ENABLED + +/** + * @brief Field sizes that can be present in CAPDU. + */ +#define CLASS_TYPE_SIZE 1U +#define INSTRUCTION_TYPE_SIZE 1U +#define PARAMETER_SIZE 2U +#define LC_SHORT_FORMAT_SIZE 1U +#define LC_LONG_FORMAT_SIZE 3U +#define LE_SHORT_FORMAT_SIZE 1U +#define LE_LONG_FORMAT_SIZE 2U + +/** + * @brief Values used to encode Lc field in CAPDU. + */ +#define LC_LONG_FORMAT_TOKEN 0x00 +#define LC_LONG_FORMAT_THR 0xFF + +/** + * @brief Values used to encode Le field in CAPDU. + */ +#define LE_FIELD_ABSENT 0U +#define LE_LONG_FORMAT_THR 0x0100 +#define LE_ENCODED_VAL_256 0x00 + + +#define STATUS_SIZE 2U ///< Size of Status field contained in RAPDU. + +/** + * @brief Function for calculating size of CAPDU. + */ +__STATIC_INLINE uint16_t nfc_t4t_comm_apdu_size_calc(nfc_t4t_comm_apdu_t const * const p_cmd_apdu) +{ + uint16_t res = CLASS_TYPE_SIZE + INSTRUCTION_TYPE_SIZE + PARAMETER_SIZE; + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) + { + res += LC_LONG_FORMAT_SIZE; + } + else + { + res += LC_SHORT_FORMAT_SIZE; + } + } + res += p_cmd_apdu->data.len; + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) + { + res += LE_LONG_FORMAT_SIZE; + } + else + { + res += LE_SHORT_FORMAT_SIZE; + } + } + return res; +} + + +/** + * @brief Function for validating arguments used by CAPDU encoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_comm_apdu_args_validate(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + if ((p_cmd_apdu == NULL) || (p_raw_data == NULL) || (p_len == NULL)) + { + return NRF_ERROR_NULL; + } + + if ((p_cmd_apdu->data.p_buff != NULL) && (p_cmd_apdu->data.len == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_comm_apdu_args_validate(p_cmd_apdu, p_raw_data, p_len); + VERIFY_SUCCESS(err_code); + + // Check if there is enough memory in the provided buffer to store described CAPDU. + uint16_t comm_apdu_len = nfc_t4t_comm_apdu_size_calc(p_cmd_apdu); + if (comm_apdu_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + *p_len = comm_apdu_len; + + // Start to encode described CAPDU in the buffer. + *p_raw_data++ = p_cmd_apdu->class_byte; + *p_raw_data++ = p_cmd_apdu->instruction; + *p_raw_data++ = MSB_16(p_cmd_apdu->parameter); + *p_raw_data++ = LSB_16(p_cmd_apdu->parameter); + + // Check if optional data field should be included. + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) // Use long data length encoding. + { + *p_raw_data++ = LC_LONG_FORMAT_TOKEN; + *p_raw_data++ = MSB_16(p_cmd_apdu->data.len); + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + else // Use short data length encoding. + { + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + memcpy(p_raw_data, p_cmd_apdu->data.p_buff, p_cmd_apdu->data.len); + p_raw_data += p_cmd_apdu->data.len; + } + + // Check if optional response length field present (Le) should be included. + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) // Use long response length encoding. + { + *p_raw_data++ = MSB_16(p_cmd_apdu->resp_len); + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + else // Use short response length encoding. + { + if (p_cmd_apdu->resp_len == LE_LONG_FORMAT_THR) + { + *p_raw_data++ = LE_ENCODED_VAL_256; + } + else + { + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + } + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating arguments used by RAPDU decoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_resp_apdu_args_validate(nfc_t4t_resp_apdu_t const * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + if ((p_resp_apdu == NULL) || (p_raw_data == NULL)) + { + return NRF_ERROR_NULL; + } + + if (len < STATUS_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_resp_apdu_args_validate(p_resp_apdu, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_clear(p_resp_apdu); + if (len != STATUS_SIZE) // Optional data field is present in RAPDU. + { + p_resp_apdu->data.len = len - STATUS_SIZE; + p_resp_apdu->data.p_buff = (uint8_t *) p_raw_data; + } + p_resp_apdu->status = uint16_big_decode(p_raw_data + p_resp_apdu->data.len); + + return NRF_SUCCESS; +} + + +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu) +{ + NRF_LOG_INFO("R-APDU status: %4X ", p_resp_apdu->status); + if (p_resp_apdu->data.p_buff != NULL) + { + NRF_LOG_INFO("R-APDU data: "); + NRF_LOG_HEXDUMP_INFO(p_resp_apdu->data.p_buff, p_resp_apdu->data.len); + } + else + { + NRF_LOG_INFO("R-APDU no data field present."); + } +} + + +#endif // NFC_T4T_APDU_ENABLED + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h new file mode 100644 index 0000000..0aa2f3d --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h @@ -0,0 +1,221 @@ +/** + * 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. + * + */ +#ifndef NFC_T4T_APDU_H__ +#define NFC_T4T_APDU_H__ + +/**@file + * + * @defgroup nfc_t4t_apdu APDU reader/writer + * @{ + * @ingroup nfc_t4t_parser + * + * @brief APDU reader/writer for Type 4 Tag communication. + * + */ + +#include <stdint.h> +#include <string.h> +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLASS_BYTE_NO_SECURE_MSG 0x00 ///< Class byte indicating no secure messaging, used in C-APDU. + +/** + * @name Parameters used when selecting instruction code in C-APDU. + * @{ + */ +#define SELECT_BY_FILE_ID 0x000C ///< Select by file identifier, first or only occurence. +#define SELECT_BY_NAME 0x0400 ///< Select by name, first or only occurence. +/** @} */ + +/** + * @name Status codes contained in R-APDU. + * @{ + */ +#define RAPDU_STATUS_CMD_COMPLETED 0x9000 ///< Command completed successfully. +#define RAPDU_STATUS_SEL_ITEM_NOT_FOUND 0x6A82 ///< Selected item has not been found. +/** @} */ + +/** + * @brief Possible instruction codes in C-APDU. + */ +typedef enum +{ + NFC_T4T_CAPDU_SELECT_INS = 0xA4, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_READ_INS = 0xB0, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_UPDATE_INS = 0xD6 ///< Code used for selecting EF or NDEF application. +} nfc_t4t_comm_apdu_ins_type_t; + +/** + * @brief APDU data field descriptor. + */ +typedef struct +{ + uint16_t len; ///< Data field length. + uint8_t * p_buff; ///< Pointer to data field. +} nfc_t4t_apdu_data_t; + +/** + * @brief Command Application Protocol Data Unit (C-APDU) descriptor. + */ +typedef struct +{ + uint8_t class_byte; ///< Class byte. + nfc_t4t_comm_apdu_ins_type_t instruction; ///< The chosen code of instruction. + uint16_t parameter; ///< Parameters associated with the instruction code. + nfc_t4t_apdu_data_t data; ///< Optional data fields (Lc + data bytes). + uint16_t resp_len; ///< Optional response length field (Le). +} nfc_t4t_comm_apdu_t; + +/** + * @brief Response Application Protocol Data Unit (R-APDU) descriptor. + */ +typedef struct +{ + uint16_t status; ///< Mandatory status field. + nfc_t4t_apdu_data_t data; ///< Optional data field. +} nfc_t4t_resp_apdu_t; + +/** + * @brief Macro for verifying R-APDU descriptor status. + * + * This macro verifies R-APDU descriptor status. It will cause the exterior + * function to return nrf_error translated from R-APDU status, if the status is + * not equal to @ref RAPDU_STATUS_CMD_COMPLETED. + * + * @param[in] P_RAPDU Pointer to R-APDU descriptor. + * + * @retval NRF_ERROR_NOT_FOUND If C-APDU select command could not find the selected item. + * @retval NRF_ERROR_INTERNAL Unknown R-APDU error. + */ +#define VERIFY_RAPDU_SUCCESS(P_RAPDU) \ + if (P_RAPDU->status == RAPDU_STATUS_SEL_ITEM_NOT_FOUND) \ + { \ + return NRF_ERROR_NOT_FOUND; \ + } \ + if (P_RAPDU->status != RAPDU_STATUS_CMD_COMPLETED) \ + { \ + return NRF_ERROR_INTERNAL; \ + } + +/** + * @brief Function for clearing C-APDU descriptor and restoring its default values. + * + * @param[in] p_cmd_apdu Pointer to C-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu); + +/** + * @brief Function for clearing R-APDU descriptor and restoring its default values. + * + * @param[in] p_resp_apdu Pointer to R-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu); + +/** + * @brief Function for encoding C-APDU. + * + * This function encodes C-APDU according to the provided descriptor. + * + * @param[in] p_cmd_apdu Pointer to the C-APDU descriptor. + * @param[out] p_raw_data Pointer to the buffer with encoded C-APDU. + * @param[in,out] p_len Size of the available memory for the C-APDU as input. + * Size of the generated C-APDU as output. + * + * @retval NRF_SUCCESS If C-APDU was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted C-APDU size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If C-APDU descriptor is invalid. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len); + +/** + * @brief Function for decoding R-APDU. + * + * This function decodes buffer with encoded R-APDU and stores results in the R-APDU descriptor. + * + * @param[out] p_resp_apdu Pointer to the R-APDU descriptor. + * @param[in] p_raw_data Pointer to the buffer with encoded R-APDU. + * @param[in] len Size of of the buffer with encoded R-APDU. + * + * @retval NRF_SUCCESS If R-APDU was encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the buffer is too small to hold a valid R-APDU. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len); + +/** + * @brief Function for printing a R-APDU descriptor. + * + * This function prints a R-APDU descriptor. + * + * @param[in] p_resp_apdu Pointer to the R-APDU descriptor. + */ +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu) +{ + memset(p_cmd_apdu, 0, sizeof(nfc_t4t_comm_apdu_t)); +} + +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu) +{ + memset(p_resp_apdu, 0, sizeof(nfc_t4t_resp_apdu_t)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_APDU_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c new file mode 100644 index 0000000..197e0a0 --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c @@ -0,0 +1,266 @@ +/** + * 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_CC_FILE_PARSER_ENABLED + +#include <string.h> +#include "nfc_t4t_cc_file.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME nfc_t4t_cc_file_parser +#if NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_CC_FILE_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_CC_FILE_PARSER_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED + +/** + * @brief Valid value range for CCLEN field. + */ +#define CC_LEN_MIN_VALUE 0x000F +#define CC_LEN_MAX_VALUE 0xFFFE + +/** + * @brief Valid major versions of Type 4 Tag specification. + */ +#define NFC_T4T_EXTENDED_MAJOR_VER 0x03 ///< Major version number allowing first TLV block to be Extended NDEF File Control TLV +#define NFC_T4T_REGULAR_MAJOR_VER 0x02 ///< Major version number allowing first TLV block to be NDEF File Control TLV + +/** + * @brief Valid value range for MLe field. + */ +#define MLE_LEN_MIN_VALUE 0x000F +#define MLE_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Valid value range for MLc field. + */ +#define MLC_LEN_MIN_VALUE 0x0001 +#define MLC_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Field sizes that are present in CC file. + */ +#define CC_LEN_FIELD_SIZE 2U +#define MAP_VER_FIELD_SIZE 1U +#define MLE_FIELD_SIZE 2U +#define MLC_FIELD_SIZE 2U + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for validating arguments used by CC file parsing procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_args_validate(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + if ( (p_t4t_cc_file == NULL) + || (p_t4t_cc_file->p_tlv_block_array == NULL) + || (p_raw_data == NULL) ) + { + return NRF_ERROR_NULL; + } + + if ( (len < CC_LEN_MIN_VALUE) || (len > CC_LEN_MAX_VALUE) ) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_t4t_cc_file->max_tlv_blocks == 0) + { + return NRF_ERROR_NO_MEM; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating CC file descriptor content. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_file_validate(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + uint16_t type = p_t4t_cc_file->p_tlv_block_array[0].type; + + if ( (p_t4t_cc_file->major_version == NFC_T4T_EXTENDED_MAJOR_VER + && type == EXTENDED_NDEF_FILE_CONTROL_TLV) || + (p_t4t_cc_file->major_version == NFC_T4T_REGULAR_MAJOR_VER + && type == NDEF_FILE_CONTROL_TLV) ) + { + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_DATA; +} + + +/** + * @brief Function for clearing all TLV blocks from CC file descriptor. + */ +__STATIC_INLINE void nfc_t4t_cc_file_clear(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + p_t4t_cc_file->tlv_count = 0; +} + + +/** + * @brief Function for adding a TLV block to the CC file descriptor. + */ +static ret_code_t nfc_t4t_tlv_block_insert(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_tlv_block_t * p_tlv_block) +{ + if (p_t4t_cc_file->tlv_count == p_t4t_cc_file->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_t4t_cc_file->p_tlv_block_array[p_t4t_cc_file->tlv_count] = *p_tlv_block; + p_t4t_cc_file->tlv_count++; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + ret_code_t err_code = nfc_t4t_cc_args_validate(p_t4t_cc_file, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + uint8_t * p_offset = p_raw_data; + nfc_t4t_cc_file_clear(p_t4t_cc_file); + + p_t4t_cc_file->len = uint16_big_decode(p_offset); + p_offset += CC_LEN_FIELD_SIZE; + + p_t4t_cc_file->major_version = MSN_GET(*p_offset); + p_t4t_cc_file->minor_version = LSN_GET(*p_offset); + p_offset += MAP_VER_FIELD_SIZE; + + p_t4t_cc_file->max_rapdu_size = uint16_big_decode(p_offset); + p_offset += MLE_FIELD_SIZE; + + p_t4t_cc_file->max_capdu_size = uint16_big_decode(p_offset); + p_offset += MLC_FIELD_SIZE; + + nfc_t4t_tlv_block_t new_block; + len -= (p_offset - p_raw_data); + while (len > 0) + { + uint16_t tlv_len = len; + err_code = nfc_t4t_file_control_tlv_parse(&new_block, p_offset, &tlv_len); + VERIFY_SUCCESS(err_code); + p_offset += tlv_len; + len -= tlv_len; + + err_code = nfc_t4t_tlv_block_insert(p_t4t_cc_file, &new_block); + VERIFY_SUCCESS(err_code); + } + + return nfc_t4t_cc_file_validate(p_t4t_cc_file); +} + + +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_array = p_t4t_cc_file->p_tlv_block_array; + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_val_t * p_tlv_value = &p_tlv_array[i].value; + if (p_tlv_value->file_id == file_id) + { + return (p_tlv_array + i); + } + } + return NULL; +} + + +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_block; + + p_tlv_block = nfc_t4t_file_content_get(p_t4t_cc_file, file_id); + if (p_tlv_block != NULL) + { + p_tlv_block->value.file = file; + return NRF_SUCCESS; + } + return NRF_ERROR_NOT_FOUND; +} + + +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + NRF_LOG_INFO("Capability Container File content: ") + NRF_LOG_INFO("CCLEN: %d ", p_t4t_cc_file->len); + NRF_LOG_INFO("Mapping Version: %d.%d ", + p_t4t_cc_file->major_version, + p_t4t_cc_file->minor_version); + NRF_LOG_INFO("MLe: %d ", p_t4t_cc_file->max_rapdu_size) + NRF_LOG_INFO("MLc: %d ", p_t4t_cc_file->max_capdu_size) + + NRF_LOG_INFO("Capability Container File contains %d File Control TLV block(s).", + p_t4t_cc_file->tlv_count); + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_tlv_printout(i, &p_t4t_cc_file->p_tlv_block_array[i]); + } +} + + +#endif // NFC_T4T_CC_FILE_PARSER_ENABLED + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h new file mode 100644 index 0000000..dc41c2c --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h @@ -0,0 +1,177 @@ +/** + * 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. + * + */ +#ifndef NFC_T4T_CC_FILE_H__ +#define NFC_T4T_CC_FILE_H__ + +/**@file + * + * @defgroup nfc_t4t_cc_file CC file parser + * @{ + * @ingroup nfc_t4t_parser + * + * @brief Capability Container file parser for Type 4 Tag. + * + */ + +#include <stdint.h> +#include "sdk_errors.h" +#include "nfc_t4t_tlv_block.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Descriptor for the Capability Container (CC) file of Type 4 Tag. + */ +typedef struct +{ + nfc_t4t_tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 4 Tag. + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks. + uint16_t len; ///< Size (bytes) of a Capability Container including this field. + uint16_t max_rapdu_size; ///< MLe field - maximum R-APDU data size (bytes). + uint16_t max_capdu_size; ///< MLc field - maximum C-APDU data size (bytes). + uint8_t major_version; ///< Major version of the supported Type 4 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 4 Tag specification. +} nfc_t4t_capability_container_t; + +/** + * @brief Macro for creating and initializing a Type 4 Tag Capability Container descriptor. + * + * This macro creates and initializes a static instance of a @ref nfc_t4t_capability_container_t + * structure and an array of @ref nfc_t4t_tlv_block_t descriptors. + * + * Use the macro @ref NFC_T4T_CC_DESC to access the Type 4 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref nfc_t4t_tlv_block_t descriptors that can be + * stored in the array. + * + */ +#define NFC_T4T_CC_DESC_DEF(NAME, MAX_BLOCKS) \ + static nfc_t4t_tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static nfc_t4t_capability_container_t NAME##_type_4_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref nfc_t4t_capability_container_t instance that was created + * with @ref NFC_T4T_CC_DESC_DEF. + * + * @param[in] NAME Name of the created descriptor instance. + */ +#define NFC_T4T_CC_DESC(NAME) (NAME##_type_4_tag) + +/** + * @brief Function for parsing raw data of a CC file, read from a Type 4 Tag. + * + * This function parses raw data of a Capability Container file and stores the results in its + * descriptor. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data. + * @param[in] len Buffer length. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NULL If any of the provided pointer arguments is NULL. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer exceeds a valid CC file length range. + * @retval NRF_ERROR_INVALID_DATA If mapping version of Type 4 Tag specification is not a + * compatible CC file structure. + * @retval Other Other error codes might be returned depending on + * @ref nfc_t4t_file_control_tlv_parse function. + */ +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len); + +/** + * @brief Function for finding File Control TLV block within the CC file descriptor. + * + * This function finds File Control TLV block that matches + * the specified file ID within the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file_id File identifier. + * + * @retval TLV Pointer to the File Control TLV. + * @retval NULL If TLV with the specified File ID was not found. + */ +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id); + +/** + * @brief Function for binding a file with its File Control TLV block. + * + * This function binds file content with its File Control TLV block, in which + * maximal file size and access conditions are stored. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file File descriptor. + * @param[in] file_id File identifier. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NOT_FOUND If the provided file ID does not match any ID stored in TLV blocks + * of the CC file. + */ +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id); + +/** + * @brief Function for printing the CC file descriptor. + * + * This function prints the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file. + */ +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_CC_FILE_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c new file mode 100644 index 0000000..f27625f --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c @@ -0,0 +1,401 @@ +/** + * 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + +#include "nfc_t4t_hl_detection_procedures.h" +#include "nfc_t4t_apdu.h" +#include "adafruit_pn532.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME nfc_t4t_hl_detection_procedures +#if NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED + +#define CC_FILE_ID 0xE103 ///< File Identifier of Capability Container. +#define FILE_ID_SIZE 2 ///< Size of File Identifier field in CC file. +#define MIN_MAX_RAPDU_SIZE 0x0F ///< Minimal value of maximal RAPDU data field size. +#define NDEF_FILE_NLEN_FIELD_SIZE 2 ///< Size of NLEN field in NDEF file. +#define NDEF_APP_PROC_RESP_LEN 256 ///< Maximal size of RAPDU data in the NDEF Tag Application Select Procedure. + +// Adafruit library limitations. +#define MAX_ADAFRUIT_RAPDU_SIZE 242 ///< Maximal value of RAPDU data field size +#define MAX_ADAFRUIT_CAPDU_SIZE 240 ///< Maximal value of CAPDU data field size + +static uint8_t m_file_id[FILE_ID_SIZE]; ///< Buffer for selected EF ID storage. +static const uint8_t m_nfc_t4t_select_ndef_app_data[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; ///< NDEF Tag Application name. +static const uint8_t m_nlen_update_value[] = {0x00, 0x00}; ///< NLEN value used in NDEF Update Procedure. + +/** + * @brief Function for performing APDU exchanges with Adafruit library. + */ +static ret_code_t nfc_t4t_apdu_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff, + uint8_t resp_len) +{ + if (resp_len > APDU_BUFF_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + uint16_t apdu_buff_len = APDU_BUFF_SIZE; + ret_code_t err_code = nfc_t4t_comm_apdu_encode(p_capdu, + p_apdu_buff, + &apdu_buff_len); + VERIFY_SUCCESS(err_code); + + err_code = adafruit_pn532_in_data_exchange(p_apdu_buff, apdu_buff_len, p_apdu_buff, &resp_len); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_resp_apdu_decode(p_rapdu, p_apdu_buff, resp_len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_printout(p_rapdu); + VERIFY_RAPDU_SUCCESS(p_rapdu); + + return err_code; +} + +/** + * @brief Function for performing APDU exchanges with Adafruit library with default response length. + */ +static ret_code_t nfc_t4t_apdu_default_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff) +{ + if (p_capdu->resp_len + sizeof(p_rapdu->status) > UINT8_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t resp_len = (uint8_t) (p_capdu->resp_len + sizeof(p_rapdu->status)); + ret_code_t err_code = nfc_t4t_apdu_exchange(p_capdu, p_rapdu, p_apdu_buff, resp_len); + + return err_code; +} + + +/** + * @brief Function for saving part of EF (contained in RAPDU) in storage buffer. + */ +static ret_code_t nfc_t4t_file_chunk_save(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint8_t * const p_storage_buff, + uint16_t storage_buff_len, + uint16_t * const p_file_offset) +{ + if (p_rapdu->data.p_buff == NULL) + { + return NRF_ERROR_NULL; + } + if ((*p_file_offset) + p_rapdu->data.len > storage_buff_len) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_storage_buff + (*p_file_offset), p_rapdu->data.p_buff, p_rapdu->data.len); + *p_file_offset += p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for updating the remaining length of the read file. + */ +static ret_code_t nfc_t4t_file_len_update(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint16_t * const p_len) +{ + if (*p_len < p_rapdu->data.len) + { + return NRF_ERROR_INVALID_DATA; + } + *p_len -= p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_ndef_tag_app_select(void) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Tag Application Select Procedure "); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_NAME; + capdu.data.p_buff = (uint8_t *) m_nfc_t4t_select_ndef_app_data; + capdu.data.len = sizeof(m_nfc_t4t_select_ndef_app_data); + capdu.resp_len = NDEF_APP_PROC_RESP_LEN; + + err_code = nfc_t4t_apdu_exchange(&capdu, &rapdu, apdu_buff, sizeof(rapdu.status)); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_file_select(uint16_t file_id) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + if (file_id != CC_FILE_ID) + { + NRF_LOG_INFO("File (ID = %4X) Select Procedure ", file_id); + } + UNUSED_RETURN_VALUE(uint16_big_encode(file_id, m_file_id)); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_FILE_ID; + capdu.data.p_buff = m_file_id; + capdu.data.len = sizeof(m_file_id); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_cc_select(void) +{ + NRF_LOG_INFO("Capability Container Select Procedure "); + + return nfc_t4t_file_select(CC_FILE_ID); +} + + +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t clen; + uint16_t file_offset = 0; + uint8_t storage_buff[CC_STORAGE_BUFF_SIZE]; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("Capability Container Read Procedure "); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = MIN_MAX_RAPDU_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + clen = uint16_big_decode(storage_buff); + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + + while (clen > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(MIN_MAX_RAPDU_SIZE, MIN(clen, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + } + + err_code = nfc_t4t_cc_file_parse(p_cc_file, storage_buff, file_offset); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Read Procedure "); + + // Read the NLEN (NDEF length) field of NDEF file. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + len = uint16_big_decode(p_ndef_file_buff) + NDEF_FILE_NLEN_FIELD_SIZE; + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + + // Read the NDEF message. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(len, MIN(p_cc_file->max_rapdu_size, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + } + + // Bind NDEF File Control TLV with NDEF file. + nfc_t4t_file_t file = + { + .p_content = p_ndef_file_buff, + .len = file_offset + }; + uint16_t file_id = uint16_big_decode(m_file_id); + err_code = nfc_t4t_file_content_set(p_cc_file, file, file_id); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint16_t file_id = uint16_big_decode(m_file_id); + uint8_t apdu_buff[APDU_BUFF_SIZE]; + nfc_t4t_tlv_block_t * p_tlv_block; + + NRF_LOG_INFO("NDEF Update Procedure "); + + if (ndef_file_buff_len < NDEF_FILE_NLEN_FIELD_SIZE) + { + return NRF_ERROR_INVALID_DATA; + } + + // Check if selected NDEF file is registered in CC file descriptor. + p_tlv_block = nfc_t4t_file_content_get(p_cc_file, file_id); + if (p_tlv_block == NULL) + { + return NRF_ERROR_NULL; + } + + // Check NDEF file capacity before writing anything to it. + len = uint16_big_decode(p_ndef_file_buff); + if ((len + NDEF_FILE_NLEN_FIELD_SIZE != ndef_file_buff_len) || + (ndef_file_buff_len > p_tlv_block->value.max_file_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Write the value 0000h in the NLEN field. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_UPDATE_INS; + capdu.parameter = file_offset; + capdu.data.p_buff = (uint8_t *) m_nlen_update_value; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + file_offset += NDEF_FILE_NLEN_FIELD_SIZE; + + // Write the NDEF message in the NDEF message field. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.data.p_buff = p_ndef_file_buff + file_offset; + capdu.data.len = MIN(len, MIN(p_cc_file->max_capdu_size, MAX_ADAFRUIT_CAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + file_offset += capdu.data.len; + len -= capdu.data.len; + } + + // Write the length of the NDEF message in the NLEN field. + capdu.parameter = 0; + capdu.data.p_buff = p_ndef_file_buff; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + NRF_LOG_RAW_INFO("\r\n"); + return NRF_SUCCESS; +} + + +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h new file mode 100644 index 0000000..7ebc56e --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h @@ -0,0 +1,184 @@ +/** + * 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. + * + */ +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_H__ +#define NFC_T4T_HL_DETECTION_PROCEDURES_H__ + +/**@file + * + * @defgroup nfc_t4t_parser NFC Type 4 Tag parser + * @ingroup nfc_t4t + * @brief Parser for Type 4 Tag data. + * + * @defgroup nfc_t4t_hl_detection_procedures High-level NDEF Detection Procedure + * @{ + * @ingroup nfc_t4t_parser + * + * @brief High-level NDEF Detection Procedure for Type 4 Tag communication. + * + */ + +#include <stdint.h> +#include "sdk_errors.h" +#include "nfc_t4t_cc_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for performing NDEF Tag Application Select Procedure. + * + * This function performs NDEF Tag Application Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.2. + * + * @retval NRF_SUCCESS If NDEF Tag Application was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF Tag Application was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_ndef_tag_app_select(void); + +/** + * @brief Function for performing Capability Container Select Procedure. + * + * This function performs Capability Container Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.3. + * + * @retval NRF_SUCCESS If the Capability Container file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If the Capability Container file was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes might be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_cc_select(void); + +/** + * @brief Function for performing Capability Container Read Procedure. + * + * This function performs Capability Container Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.4. + * + * @param[out] p_cc_file Pointer to the Capability Container descriptor. + * + * @retval NRF_SUCCESS If Capability Container file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or CC file storage buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If CCLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on functions + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_cc_file_parse, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file); + +/** + * @brief Function for performing NDEF Select Procedure. + * + * This function performs NDEF Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.5. + * + * @param[in] file_id File Identifier to choose the correct file. + * + * @retval NRF_SUCCESS If NDEF file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF file was not found. + * @retval NRF_ERROR_NO_MEM If APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_file_select(uint16_t file_id); + +/** + * @brief Function for performing NDEF Read Procedure. + * + * This function performs NDEF Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.6. + * + * @param[in,out] p_cc_file Pointer to the Capability Container descriptor. + * @param[out] p_ndef_file_buff Pointer to the buffer where the NDEF file will be stored. + * @param[in] ndef_file_buff_len Length of the provided NDEF file buffer. + * + * @retval NRF_SUCCESS If NDEF file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If NLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_set, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** + * @brief Function for performing NDEF Update Procedure. + * + * This function performs NDEF Update Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.7. + * + * @param[in] p_cc_file Pointer to the Capability Container descriptor. + * @param[in] p_ndef_file_buff Pointer to the buffer with NDEF file. + * @param[in] ndef_file_buff_len Length of the provided NDEF file. + * + * @retval NRF_SUCCESS If NDEF file was successfully updated. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_INVALID_DATA If NDEF file buffer is smaller than NLEN field size. + * @retval NRF_ERROR_INVALID_LENGTH If NLEN value is not coherent with NDEF file buffer length + * or if buffer length is bigger than maximal file size. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_get, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_HL_DETECTION_PROCEDURES_H__ */ diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c new file mode 100644 index 0000000..028018b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c @@ -0,0 +1,327 @@ +/** + * 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_TLV_BLOCK_PARSER_ENABLED + +#include <string.h> +#include "nfc_t4t_tlv_block.h" +#include "app_util.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME nfc_t4t_tlv_block_parser +#if NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); +#else // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#include "nrf_log.h" +#endif // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED + +#define TLV_TYPE_FIELD_LEN 1U ///< Length of a type field. + +/** + * @brief TLV length field related defines. + */ +#define TLV_LEN_SHORT_FIELD_LEN 1U ///< Length of a short length field. +#define TLV_LEN_LONG_FIELD_LEN 3U ///< Length of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN 0xFF ///< Value indicating the use of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN_SIZE 1U ///< Size of long format token. +#define TLV_LEN_LONG_FORMAT_MIN_VALUE 0xFF ///< The minimal value of length field that can be used in long format. + +/** + * @brief Possible sizes of TLV block. + */ +#define TLV_MIN_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_SHORT_FIELD_LEN) +#define TLV_MIN_LONG_FORMAT_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_LONG_FIELD_LEN) +#define TLV_MIN_VALUE_FIELD_SIZE 6U + +/** + * @brief Field sizes that are present in TLV block. + */ +#define FILE_CONTROL_FILE_ID_FIELD_SIZE 2U +#define FILE_CONTROL_READ_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_COMMON_FIELDS_SIZE (FILE_CONTROL_FILE_ID_FIELD_SIZE \ + + FILE_CONTROL_READ_ACCESS_FIELD_SIZE \ + + FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE) + +/** + * @brief Invalid values for File Identifier field. + */ +#define FILE_ID_INVALID_VALUE_0 0x0000 +#define FILE_ID_INVALID_VALUE_1 0xE102 +#define FILE_ID_INVALID_VALUE_2 0xE103 +#define FILE_ID_INVALID_VALUE_3 0x3F00 +#define FILE_ID_INVALID_VALUE_4 0x3FFF +#define FILE_ID_INVALID_VALUE_5 0xFFFF + +/** + * @brief NDEF file related defines. + */ +#define NDEF_FILE_MAX_SIZE_FIELD_SIZE 2U +#define NDEF_FILE_MAX_SIZE_MIN_VAL 0x0005 +#define NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Proprietary file related defines. + */ +#define PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE 2U +#define PROPRIETARY_FILE_MAX_SIZE_MIN_VAL 0x0003 +#define PROPRIETARY_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define PROPRIETARY_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Extended NDEF file related defines. + */ +#define EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE 4U +#define EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL 0x0000FFFF +#define EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFFFFFE +#define EXTENDED_NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Validates maximum file size field range. This field is present in every File Control TLV. + */ +#define NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(VALUE, MIN, MAX) \ + if ( ( (VALUE) < (MIN) ) || ( (VALUE) > (MAX) ) ) \ + { \ + return NRF_ERROR_INVALID_DATA; \ + } + + +/** + * @brief Function for validating all possible types of File Control TLV. + */ +__STATIC_INLINE ret_code_t nfc_t4t_file_control_tl_validate(nfc_t4t_tlv_block_t * p_file_control_tlv) +{ + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case PROPRIETARY_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == PROPRIETARY_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == EXTENDED_NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_DATA; + } +} + + +/** + * @brief Function for parsing value field of File Control TLV. + */ +static ret_code_t nfc_t4t_file_control_value_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_value_buff) +{ + nfc_t4t_file_control_val_t * p_control_tlv_val; + + // Handle File Identifier field. + p_control_tlv_val = &p_file_control_tlv->value; + p_control_tlv_val->file_id = uint16_big_decode(p_value_buff); + p_value_buff += FILE_CONTROL_FILE_ID_FIELD_SIZE; + + switch (p_control_tlv_val->file_id) + { + case FILE_ID_INVALID_VALUE_0: + case FILE_ID_INVALID_VALUE_1: + case FILE_ID_INVALID_VALUE_2: + case FILE_ID_INVALID_VALUE_3: + case FILE_ID_INVALID_VALUE_4: + case FILE_ID_INVALID_VALUE_5: + return NRF_ERROR_INVALID_DATA; + + default: + break; + } + + // Handle Max file size field. + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + NDEF_FILE_MAX_SIZE_MIN_VAL, + NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + PROPRIETARY_FILE_MAX_SIZE_MIN_VAL, + PROPRIETARY_FILE_MAX_SIZE_MAX_VAL); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint32_big_decode(p_value_buff); + p_value_buff += EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL, + EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + } + + // Handle read access condition field. + p_control_tlv_val->read_access = *p_value_buff; + p_value_buff += FILE_CONTROL_READ_ACCESS_FIELD_SIZE; + + // Handle write access condition field. + p_control_tlv_val->write_access = *p_value_buff; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len) +{ + ret_code_t err_code; + uint8_t * p_offset = p_raw_data; + + if (*p_len < TLV_MIN_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + memset(p_file_control_tlv, 0, sizeof(nfc_t4t_tlv_block_t)); + + // Handle type field of TLV block. + p_file_control_tlv->type = *p_offset; + p_offset += TLV_TYPE_FIELD_LEN; + + // Handle length field of TLV block. + if (*p_offset == TLV_LEN_LONG_FORMAT_TOKEN) + { + if (*p_len < TLV_MIN_LONG_FORMAT_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_file_control_tlv->length = uint16_big_decode(p_offset + TLV_LEN_LONG_FORMAT_TOKEN_SIZE); + p_offset += TLV_LEN_LONG_FIELD_LEN; + + if (p_file_control_tlv->length < TLV_LEN_LONG_FORMAT_MIN_VALUE) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + p_file_control_tlv->length = *p_offset; + p_offset += TLV_LEN_SHORT_FIELD_LEN; + } + + // Calculate the total TLV block size. + uint16_t tlv_block_len = (p_offset - p_raw_data) + p_file_control_tlv->length; + if (*p_len < tlv_block_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + *p_len = tlv_block_len; + + // Validate if type and length fields contain values supported by Type 4 Tag. + err_code = nfc_t4t_file_control_tl_validate(p_file_control_tlv); + VERIFY_SUCCESS(err_code); + + // Handle value field of TLV block. + err_code = nfc_t4t_file_control_value_parse(p_file_control_tlv, p_offset); + return err_code; +} + + +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block) +{ + NRF_LOG_INFO("%d file Control TLV", num); + switch (p_t4t_tlv_block->type) + { + case NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: NDEF File Control (0x%02x)", p_t4t_tlv_block->type); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Proprietary File Control (0x%02x)", p_t4t_tlv_block->type); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Extended NDEF File Control (0x%02x)", p_t4t_tlv_block->type); + break; + + default: + NRF_LOG_INFO("Type: Unknown (0x%02x)", p_t4t_tlv_block->type); + } + NRF_LOG_INFO("Length (in bytes): %d", p_t4t_tlv_block->length); + + nfc_t4t_file_control_val_t * p_tlv_val = &p_t4t_tlv_block->value; + NRF_LOG_INFO("File Identifier: 0x%04X ", p_tlv_val->file_id); + NRF_LOG_INFO("Maximum file size: %d ", p_tlv_val->max_file_size); + NRF_LOG_INFO("Read access condition: 0x%02X ", p_tlv_val->read_access); + NRF_LOG_INFO("Write access condition: 0x%02x ", p_tlv_val->write_access); + + if (p_tlv_val->file.p_content != NULL) + { + NRF_LOG_INFO("NDEF file content present. Length: %d ", p_tlv_val->file.len); + NRF_LOG_HEXDUMP_INFO(p_tlv_val->file.p_content, p_tlv_val->file.len); + } + else + { + NRF_LOG_INFO("NDEF file content is not present "); + } +} + + +#endif // NFC_T4T_TLV_BLOCK_PARSER_ENABLED + diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h new file mode 100644 index 0000000..f67396b --- /dev/null +++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h @@ -0,0 +1,147 @@ +/** + * 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. + * + */ +#ifndef NFC_T4T_TLV_BLOCK_H__ +#define NFC_T4T_TLV_BLOCK_H__ + +/**@file + * + * @defgroup nfc_t4t_tlv_block File Control TLV block parser for Type 4 Tag. + * @{ + * @ingroup nfc_t4t_cc_file + * + * @brief File Control TLV block parser for Type 4 Tag (T4T). + * + */ + +#include <stdint.h> +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONTROL_FILE_READ_ACCESS_GRANTED 0x00 ///< Read access granted without any security. + +/** + * @name Possible values of file write access condition field. + * @{ + */ +#define CONTROL_FILE_WRITE_ACCESS_GRANTED 0x00 ///< Write access granted without any security. +#define CONTROL_FILE_WRITE_ACCESS_DISABLED 0xFF ///< No write access granted without any security (read-only). +/** @} */ + +/** + * @brief Possible types of File Control TLV for Type 4 Tag. + */ +typedef enum +{ + NDEF_FILE_CONTROL_TLV = 0x04, ///< Control information concerning the EF file with short NDEF message. + PROPRIETARY_FILE_CONTROL_TLV = 0x05, ///< Control information concerning the Proprietary file with proprietary data. + EXTENDED_NDEF_FILE_CONTROL_TLV = 0x06 ///< Control information concerning the EF file with long NDEF message. +} nfc_t4t_tlv_block_types_t; + +/** + * @brief File content descriptor. + */ +typedef struct +{ + uint8_t * p_content; ///< Pointer to the file content. + uint16_t len; ///< Length of file content. +} nfc_t4t_file_t; + +/** + * @brief Extended NDEF/NDEF/Proprietary File Control Value descriptor. + */ +typedef struct +{ + nfc_t4t_file_t file; ///< Pointer to the described file content. + uint32_t max_file_size; ///< Maximum size (in bytes) of the file. + uint16_t file_id; ///< File identifier. + uint8_t read_access; ///< File read access condition. + uint8_t write_access; ///< File write access condition. +} nfc_t4t_file_control_val_t; + +/** + * @brief File Control TLV block descriptor. + */ +typedef struct +{ + nfc_t4t_file_control_val_t value; ///< Value field descriptor. + uint16_t length; ///< Length of the value field. + uint8_t type; ///< Type of the TLV block. +} nfc_t4t_tlv_block_t; + +/** + * @brief Function for parsing raw data of File Control TLV, read from a Type 4 Tag. + * + * This function parses raw data of File Control TLV and stores the results in its + * descriptor. + * + * @param[in,out] p_file_control_tlv Pointer to the File Control TLV that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw TLV data. + * @param[in,out] p_len In: Buffer length with TLV blocks. + * Out: Total length of first identified TLV within the buffer. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer length is too small for TLV block. + * @retval NRF_ERROR_INVALID_DATA If any TLV block field contains invalid data. + */ +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len); + +/** + * @brief Function for printing TLV block descriptor. + * + * This function prints TLV block descriptor. + * + * @param[in] num TLV block number. + * @param[in] p_t4t_tlv_block Pointer to the TLV block descriptor. + */ +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_TLV_BLOCK_H__ */ |