初始版本
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,524 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
|
||||
/** @} */
|
||||
164
components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c
Normal file
164
components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
199
components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h
Normal file
199
components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* Copyright (c) 2012 - 2020, 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)
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2012 - 2020, 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__
|
||||
|
||||
/** @} */
|
||||
@@ -0,0 +1,576 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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 "nrf_sdh_ble.h"
|
||||
#include "nrf_ble_lesc.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 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. */
|
||||
|
||||
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_sec_params_t m_sec_param; /**< Current Peer Manager secure parameters configuration. */
|
||||
|
||||
static uint8_t m_connections = 0; /**< Number of active connections. */
|
||||
|
||||
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 NRF_ERROR_NULL If LESC oob data is missing.
|
||||
* @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 = nrf_ble_lesc_own_oob_data_generate();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
ble_gap_lesc_oob_data_t * p_lesc_oob_data = nrf_ble_lesc_own_oob_data_get();
|
||||
VERIFY_PARAM_NOT_NULL(p_lesc_oob_data);
|
||||
|
||||
// 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,
|
||||
p_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 = nrf_ble_lesc_own_oob_data_generate();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
ble_gap_lesc_oob_data_t * p_lesc_oob_data = nrf_ble_lesc_own_oob_data_get();
|
||||
VERIFY_PARAM_NOT_NULL(p_lesc_oob_data);
|
||||
|
||||
// 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,
|
||||
p_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 &&
|
||||
err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)
|
||||
{
|
||||
VERIFY_SUCCESS(err_code);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// Generate LESC OOB data
|
||||
err_code = nrf_ble_lesc_own_oob_data_generate();
|
||||
APP_ERROR_CHECK(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;
|
||||
|
||||
// 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 = nrf_ble_lesc_keypair_generate();
|
||||
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 = nrf_ble_lesc_own_oob_data_generate();
|
||||
VERIFY_SUCCESS(err_code);
|
||||
|
||||
// Update NDEF message with new LESC OOB data.
|
||||
err_code = nfc_lesc_data_update(nrf_ble_lesc_own_oob_data_get());
|
||||
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;
|
||||
|
||||
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();
|
||||
if (err_code != NRF_ERROR_BUSY)
|
||||
{
|
||||
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)
|
||||
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
@@ -0,0 +1,411 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
107
components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c
Normal file
107
components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
165
components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h
Normal file
165
components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
183
components/nfc/ndef/generic/message/nfc_ndef_msg.c
Normal file
183
components/nfc/ndef/generic/message/nfc_ndef_msg.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
197
components/nfc/ndef/generic/message/nfc_ndef_msg.h
Normal file
197
components/nfc/ndef/generic/message/nfc_ndef_msg.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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
|
||||
|
||||
191
components/nfc/ndef/generic/record/nfc_ndef_record.c
Normal file
191
components/nfc/ndef/generic/record/nfc_ndef_record.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
311
components/nfc/ndef/generic/record/nfc_ndef_record.h
Normal file
311
components/nfc/ndef/generic/record/nfc_ndef_record.h
Normal file
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
|
||||
97
components/nfc/ndef/launchapp/nfc_launchapp_msg.c
Normal file
97
components/nfc/ndef/launchapp/nfc_launchapp_msg.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
100
components/nfc/ndef/launchapp/nfc_launchapp_msg.h
Normal file
100
components/nfc/ndef/launchapp/nfc_launchapp_msg.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
|
||||
|
||||
107
components/nfc/ndef/launchapp/nfc_launchapp_rec.c
Normal file
107
components/nfc/ndef/launchapp/nfc_launchapp_rec.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
205
components/nfc/ndef/launchapp/nfc_launchapp_rec.h
Normal file
205
components/nfc/ndef/launchapp/nfc_launchapp_rec.h
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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
|
||||
94
components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c
Normal file
94
components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
123
components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h
Normal file
123
components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
|
||||
|
||||
163
components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c
Normal file
163
components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
166
components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h
Normal file
166
components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
219
components/nfc/ndef/parser/record/nfc_ndef_record_parser.c
Normal file
219
components/nfc/ndef/parser/record/nfc_ndef_record_parser.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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)
|
||||
100
components/nfc/ndef/parser/record/nfc_ndef_record_parser.h
Normal file
100
components/nfc/ndef/parser/record/nfc_ndef_record_parser.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__
|
||||
107
components/nfc/ndef/text/nfc_text_rec.c
Normal file
107
components/nfc/ndef/text/nfc_text_rec.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
161
components/nfc/ndef/text/nfc_text_rec.h
Normal file
161
components/nfc/ndef/text/nfc_text_rec.h
Normal file
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
72
components/nfc/ndef/uri/nfc_uri_msg.c
Normal file
72
components/nfc/ndef/uri/nfc_uri_msg.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
95
components/nfc/ndef/uri/nfc_uri_msg.h
Normal file
95
components/nfc/ndef/uri/nfc_uri_msg.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
87
components/nfc/ndef/uri/nfc_uri_rec.c
Normal file
87
components/nfc/ndef/uri/nfc_uri_rec.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
189
components/nfc/ndef/uri/nfc_uri_rec.h
Normal file
189
components/nfc/ndef/uri/nfc_uri_rec.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__
|
||||
126
components/nfc/platform/nfc_platform.c
Normal file
126
components/nfc/platform/nfc_platform.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 2020, 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_PLATFORM)
|
||||
|
||||
#include "nfc_platform.h"
|
||||
#include "nrf_drv_clock.h"
|
||||
|
||||
#define NRF_LOG_MODULE_NAME nfc_platform
|
||||
#if NFC_PLATFORM_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL NFC_PLATFORM_LOG_LEVEL
|
||||
#define NRF_LOG_INFO_COLOR NFC_PLATFORM_INFO_COLOR
|
||||
#define NRF_LOG_DEBUG_COLOR NFC_PLATFORM_DEBUG_COLOR
|
||||
#include "nrf_log.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
#else // NFC_PLATFORM_LOG_ENABLED
|
||||
#define NRF_LOG_LEVEL 0
|
||||
#include "nrf_log.h"
|
||||
#endif // NFC_PLATFORM_LOG_ENABLED
|
||||
|
||||
/* Static data */
|
||||
static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure. */
|
||||
|
||||
/**@brief Function for handling events from the Clock module.
|
||||
*
|
||||
* @param[in] event Clock event.
|
||||
*
|
||||
*/
|
||||
static inline void 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 */
|
||||
nrfx_nfct_state_force(NRFX_NFCT_STATE_ACTIVATED);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* No implementation required */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nrfx_err_t nfc_platform_setup(void)
|
||||
{
|
||||
nrfx_err_t err_code;
|
||||
|
||||
/* Initialize the Clock module for handling high precision clock requests */
|
||||
m_clock_handler_item.event_handler = clock_event_handler;
|
||||
m_clock_handler_item.p_next = NULL;
|
||||
|
||||
err_code = nrf_drv_clock_init();
|
||||
if (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)
|
||||
{
|
||||
err_code = NRFX_SUCCESS;
|
||||
}
|
||||
else if (err_code != NRF_SUCCESS)
|
||||
{
|
||||
return NRFX_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
NRF_LOG_DEBUG("Utils init");
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
void nfc_platform_event_handler(nrfx_nfct_evt_t const * p_event)
|
||||
{
|
||||
switch (p_event->evt_id)
|
||||
{
|
||||
case NRFX_NFCT_EVT_FIELD_DETECTED:
|
||||
NRF_LOG_DEBUG("Field detected");
|
||||
nrf_drv_clock_hfclk_request(&m_clock_handler_item);
|
||||
break;
|
||||
|
||||
case NRFX_NFCT_EVT_FIELD_LOST:
|
||||
NRF_LOG_DEBUG("Field lost");
|
||||
nrf_drv_clock_hfclk_release();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* No implementation required */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NRF_MODULE_ENABLED(NFC_PLATFORM)
|
||||
98
components/nfc/platform/nfc_platform.h
Normal file
98
components/nfc/platform/nfc_platform.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2018 - 2020, 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_PLATFORM_H__
|
||||
#define NFC_PLATFORM_H__
|
||||
|
||||
/** @file
|
||||
*
|
||||
* @addtogroup nfc_api
|
||||
*
|
||||
* @defgroup nfc_platform Platform-specific module for NFC
|
||||
* @{
|
||||
* @ingroup nfc_api
|
||||
* @brief @tagAPI52 Platform-specific module for Near Field Communication Tag (NFCT).
|
||||
*
|
||||
* This module is used to set up platform-specific components that are required for NFC, and to
|
||||
* activate NFCT peripheral when all necessary conditions are fulfilled.
|
||||
*
|
||||
* @note Before the NFCT peripheral enters the ACTIVATED state, the HFXO must be running. To fulfill
|
||||
* this requirement, this module uses the clock management module.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nrfx_nfct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function for initializing platform-specific modules required by NFC.
|
||||
*
|
||||
* This function sets up clock managing interface and other platform specific components
|
||||
* that are required for NFC.
|
||||
*
|
||||
* @retval NRFX_SUCCESS If the NFC module is initialized successfully. If one
|
||||
* of the arguments is invalid, an error code is returned.
|
||||
*/
|
||||
nrfx_err_t nfc_platform_setup(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Function for handling NFCT events that require platform-specific actions.
|
||||
*
|
||||
* This function is used by the NFC platform module to observe NFC events. This event flow is
|
||||
* necessary to track in order to determine when HFXO must be running and when the NFCT peripheral must
|
||||
* be activated.
|
||||
*
|
||||
* @param[in] p_event NFCT driver event.
|
||||
*/
|
||||
void nfc_platform_event_handler(nrfx_nfct_evt_t const * p_event);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* NFC_PLATFORM_H__ */
|
||||
|
||||
36
components/nfc/t2t_lib/license.txt
Normal file
36
components/nfc/t2t_lib/license.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
Copyright (c) 2015 - 2020, 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.
|
||||
271
components/nfc/t2t_lib/nfc_t2t_lib.h
Normal file
271
components/nfc/t2t_lib/nfc_t2t_lib.h
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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.
|
||||
*
|
||||
* This function allows to set an NFC configuration parameter.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* 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__
|
||||
BIN
components/nfc/t2t_lib/nfc_t2t_lib_keil.lib
Normal file
BIN
components/nfc/t2t_lib/nfc_t2t_lib_keil.lib
Normal file
Binary file not shown.
679
components/nfc/t2t_parser/nfc_t2t_parser.c
Normal file
679
components/nfc/t2t_parser/nfc_t2t_parser.c
Normal file
@@ -0,0 +1,679 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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)
|
||||
195
components/nfc/t2t_parser/nfc_t2t_parser.h
Normal file
195
components/nfc/t2t_parser/nfc_t2t_parser.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__ */
|
||||
102
components/nfc/t2t_parser/nfc_tlv_block.h
Normal file
102
components/nfc/t2t_parser/nfc_tlv_block.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2015 - 2020, 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__ */
|
||||
36
components/nfc/t4t_lib/license.txt
Normal file
36
components/nfc/t4t_lib/license.txt
Normal file
@@ -0,0 +1,36 @@
|
||||
Copyright (c) 2016 - 2020, 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.
|
||||
332
components/nfc/t4t_lib/nfc_t4t_lib.h
Normal file
332
components/nfc/t4t_lib/nfc_t4t_lib.h
Normal file
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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 Pointer to current data of NDEF message
|
||||
* @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. Buffer can be changed during the lifetime of the emulation,
|
||||
* when NDEF READ or UPDATE procedure is pending, and it will be changed after
|
||||
* this procedure is finished. To perform this procedure safely use
|
||||
* critical sections or disable the interrupts.
|
||||
*
|
||||
* @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_NOT_SUPPORTED If the new buffer has a different length than the first one.
|
||||
* @retval NRF_ERROR_INVALID_DATA If the provided buffer is the currently used buffer.
|
||||
*/
|
||||
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 an NFC configuration parameter.
|
||||
*
|
||||
* @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__
|
||||
BIN
components/nfc/t4t_lib/nfc_t4t_lib_keil.lib
Normal file
BIN
components/nfc/t4t_lib/nfc_t4t_lib_keil.lib
Normal file
Binary file not shown.
261
components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c
Normal file
261
components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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
|
||||
|
||||
221
components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h
Normal file
221
components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h
Normal file
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__ */
|
||||
266
components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c
Normal file
266
components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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
|
||||
|
||||
177
components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h
Normal file
177
components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__ */
|
||||
@@ -0,0 +1,401 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__ */
|
||||
327
components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c
Normal file
327
components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c
Normal file
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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
|
||||
|
||||
147
components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h
Normal file
147
components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright (c) 2016 - 2020, 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__ */
|
||||
Reference in New Issue
Block a user