初始版本

This commit is contained in:
xiaozhengsheng
2025-08-19 09:49:41 +08:00
parent 10f1ddf1c1
commit 6df0f7d96e
2974 changed files with 1712873 additions and 54 deletions

View 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)

View 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__

View File

@@ -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)

View File

@@ -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__
/** @} */

View File

@@ -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)

View File

@@ -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__

View File

@@ -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)

View File

@@ -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__

View File

@@ -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)

View File

@@ -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__

View File

@@ -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)

View File

@@ -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__

View 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)

View 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__

View File

@@ -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)

View File

@@ -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__