/**
*********************************************************************************************************
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
*********************************************************************************************************
* @file gap_storage_le.h
* @brief key storage function.
* @details
* @author jane
* @date 2016-02-18
* @version v1.0
* *********************************************************************************************************
*/
/*============================================================================*
* Define to prevent recursive inclusion
*============================================================================*/
#ifndef FLASH_KEY_MGR_LE_H
#define FLASH_KEY_MGR_LE_H
#ifdef __cplusplus
extern "C"
{
#endif
/*============================================================================*
* Header Files
*============================================================================*/
#include "upperstack_config.h"
#include "gap.h"
#include "gap_le_types.h"
/** @defgroup GAP_LE_STORAGE GAP LE Storage
* @brief GAP LE Storage
* @{
*/
/*============================================================================*
* Macros
*============================================================================*/
/** @defgroup GAP_LE_STORAGE_Exported_Macros GAP LE Storage Exported Macros
* @{
*/
/** @defgroup GAP_LE_STORAGE_BITS LE Key Storage Bits
* @{
*/
#define LE_KEY_STORE_REMOTE_BD_BIT 0x01
#define LE_KEY_STORE_LOCAL_LTK_BIT 0x02
#define LE_KEY_STORE_REMOTE_LTK_BIT 0x04
#define LE_KEY_STORE_REMOTE_IRK_BIT 0x08
#define LE_KEY_STORE_LOCAL_CSRK_BIT 0x10
#define LE_KEY_STORE_REMOTE_CSRK_BIT 0x20
#define LE_KEY_STORE_CCCD_DATA_BIT 0x40
#define LE_KEY_STORE_LOCAL_IRK_BIT 0x80
#define LE_KEY_STORE_REMOTE_CLIENT_SUPPORTED_FEATURES_BIT 0x0100
#define LE_KEY_STORE_REMOTE_SRV_CHANGE_AWARE_STATE_BIT 0x0200
#define LE_KEY_STORE_LOCAL_BD_BIT 0x8000
/**
* @}
*/
/** End of GAP_LE_STORAGE_Exported_Macros
* @}
*/
/*============================================================================*
* Types
*============================================================================*/
/** @defgroup GAP_LE_STORAGE_Exported_Types GAP LE Storage Exported Types
* @{
*/
/** @brief Local Device Name */
typedef struct
{
uint8_t local_name[40];
} T_LOCAL_NAME;
/** @brief Local Device Appearance */
typedef struct
{
uint16_t local_appearance;
uint8_t padding[2];
} T_LOCAL_APPEARANCE;
/** @brief Local IRK */
typedef struct
{
uint8_t local_irk[16];
} T_LOCAL_IRK;
/** @brief Remote Bluetooth device address info */
typedef struct
{
uint8_t addr[6];
uint8_t remote_bd_type;
uint8_t bond_flags;
} T_LE_REMOTE_BD;
#if F_BT_LE_PRIVACY_SUPPORT
/** @brief LE privacy information */
typedef struct
{
bool is_discov;
bool central_addr_resolv;
bool resolv_addr_only;
} T_LE_PRIVACY_INFO;
#endif
/** @brief LE CCCD info */
typedef struct
{
uint16_t handle;
uint16_t ccc_bits;
} T_LE_CCCD_ELEM;
typedef struct
{
uint8_t data_length;
uint8_t padding[3];
uint8_t data[1];
} T_LE_CCCD;
/** @brief LE Key Type */
typedef enum
{
LE_KEY_UNAUTHEN = 0x04, /**< SSP generated link key without MITM protection. */
LE_KEY_AUTHEN = 0x05, /**< SSP generated link key with MITM protection. */
LE_KEY_UNAUTHEN_P256 = 0x07, /**< Security Connections generated link key without MITM protection. */
LE_KEY_AUTHEN_P256 = 0x08, /**< Security Connections link key with MITM protection. */
} T_LE_KEY_TYPE;
/** @brief LE key entry */
typedef struct
{
bool is_used;
uint8_t idx;
uint16_t flags;
uint8_t local_bd_type;
uint8_t app_data;
uint8_t reserved[2];
T_LE_REMOTE_BD remote_bd;
T_LE_REMOTE_BD resolved_remote_bd;
uint8_t local_bd_addr[6];
} T_LE_KEY_ENTRY;
typedef struct
{
uint16_t flags;
T_LE_REMOTE_BD remote_bd;
uint8_t local_ltk[32];
uint8_t remote_ltk[32];
uint8_t remote_irk[24];
} T_LE_DEV_INFO;
typedef struct
{
uint8_t link_key_length;
uint8_t padding[3];
uint8_t key[28];
} T_LE_LTK;
/** End of GAP_LE_STORAGE_Exported_Types
* @}
*/
/*============================================================================*
* Functions
*============================================================================*/
/**
* @defgroup GAP_LE_STORAGE_EXPORT_Functions GAP LE Storage Exported Functions
*
* @{
*/
/**
* @brief Save local device name to flash.
* @param[in] p_data pointer to local device name
* @return Operation result.
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
p_gap_data->msg_type);
if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
{
switch (p_gap_data->msg_data.opcode)
{
case GAPS_WRITE_DEVICE_NAME:
{
T_LOCAL_NAME device_name;
memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
device_name.local_name[p_gap_data->msg_data.len] = 0;
flash_save_local_name(&device_name);
}
break;
case GAPS_WRITE_APPEARANCE:
{
uint16_t appearance_val;
T_LOCAL_APPEARANCE appearance;
LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
appearance.local_appearance = appearance_val;
flash_save_local_appearance(&appearance);
}
break;
default:
break;
}
}
else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
{
if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE)
{
APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE");
}
}
return result;
}
* \endcode
*/
uint32_t flash_save_local_name(T_LOCAL_NAME *p_data);
/**
* @brief Load local device name from flash.
* @param[in] p_data pointer to local device name
* @return Operation result.
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
void test()
{
uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest";
uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
T_LOCAL_APPEARANCE appearance_local;
T_LOCAL_NAME local_device_name;
if (flash_load_local_appearance(&appearance_local) == 0)
{
if (appearance_local.local_appearance != 0xffff)
{
appearance = appearance_local.local_appearance;
}
}
if (flash_load_local_name(&local_device_name) == 0)
{
if (local_device_name.local_name[0] != 0xff)
{
memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN);
}
}
}
* \endcode
*/
uint32_t flash_load_local_name(T_LOCAL_NAME *p_data);
/**
* @brief Save local device appearance to flash.
* @param[in] p_data Pointer to local device name
* @return Operation result
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
T_APP_RESULT gap_service_callback(T_SERVER_ID service_id, void *p_para)
{
T_APP_RESULT result = APP_RESULT_SUCCESS;
T_GAPS_CALLBACK_DATA *p_gap_data = (T_GAPS_CALLBACK_DATA *)p_para;
APP_PRINT_INFO2("gap_service_callback conn_id = %d msg_type = %d\n", p_gap_data->conn_id,
p_gap_data->msg_type);
if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_WRITE_CHAR_VALUE)
{
switch (p_gap_data->msg_data.opcode)
{
case GAPS_WRITE_DEVICE_NAME:
{
T_LOCAL_NAME device_name;
memcpy(device_name.local_name, p_gap_data->msg_data.p_value, p_gap_data->msg_data.len);
device_name.local_name[p_gap_data->msg_data.len] = 0;
flash_save_local_name(&device_name);
}
break;
case GAPS_WRITE_APPEARANCE:
{
uint16_t appearance_val;
T_LOCAL_APPEARANCE appearance;
LE_ARRAY_TO_UINT16(appearance_val, p_gap_data->msg_data.p_value);
appearance.local_appearance = appearance_val;
flash_save_local_appearance(&appearance);
}
break;
default:
break;
}
}
else if (p_gap_data->msg_type == SERVICE_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
{
if (p_gap_data->msg_data.opcode == GATT_SERVICE_CHANGE_CCCD_ENABLE)
{
APP_PRINT_INFO0("GATT_SERVICE_CHANGE_CCCD_ENABLE");
}
}
return result;
}
* \endcode
*/
uint32_t flash_save_local_appearance(T_LOCAL_APPEARANCE *p_data);
/**
* @brief Load local device appearance from flash.
* @param[in] p_data Pointer to local device name
* @return Operation result
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
void test()
{
uint8_t device_name[GAP_DEVICE_NAME_LEN] = "BB3_GapTest";
uint16_t appearance = GAP_GATT_APPEARANCE_UNKNOWN;
uint8_t appearance_prop = GAPS_PROPERTY_WRITE_ENABLE;
uint8_t device_name_prop = GAPS_PROPERTY_WRITE_ENABLE;
T_LOCAL_APPEARANCE appearance_local;
T_LOCAL_NAME local_device_name;
if (flash_load_local_appearance(&appearance_local) == 0)
{
if (appearance_local.local_appearance != 0xffff)
{
appearance = appearance_local.local_appearance;
}
}
if (flash_load_local_name(&local_device_name) == 0)
{
if (local_device_name.local_name[0] != 0xff)
{
memcpy(device_name, local_device_name.local_name, GAP_DEVICE_NAME_LEN);
}
}
}
* \endcode
*/
uint32_t flash_load_local_appearance(T_LOCAL_APPEARANCE *p_data);
#if F_BT_LE_LOCAL_IRK_SETTING_SUPPORT
/**
* @brief Save local IRK to flash.
* @param[in] p_data Pointer to local device name
* @return Operation result
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
void test()
{
T_LOCAL_IRK irk = {0x01,0x02,0x03,};
flash_save_local_irk(&irk);
}
* \endcode
*/
uint32_t flash_save_local_irk(T_LOCAL_IRK *p_data);
/**
* @brief Load local IRK from flash.
* @param[in] p_data Pointer to local device name
* @return Operation result
* @retval 0 Operation success.
* @retval Others Operation failure.
*
* Example usage
* \code{.c}
void test()
{
T_LOCAL_IRK irk;
flash_load_local_irk(&irk);
}
* \endcode
*/
uint32_t flash_load_local_irk(T_LOCAL_IRK *p_data);
#endif
/**
* @brief Find key entry by bluetooth device address and address type.
*
* @param[in] bd_addr Remote bluetooth device address.
* @param[in] bd_type Remote bluetooth device address type.
* @return p_entry Pointer to the found key entry.
* @retval null No entry found.
* @retval others Pointer to the found key entry.
*/
T_LE_KEY_ENTRY *le_find_key_entry(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type);
/**
* @brief Find key entry by bluetooth device address and address type.
*
* @param[in] remote_bd_addr Remote bluetooth device address.
* @param[in] remote_bd_type Remote bluetooth device address type.
* @param[in] local_bd_addr Local bluetooth device address.
* @param[in] local_bd_type Local bluetooth device address type.
* @return p_entry Pointer to the found key entry.
* @retval null No entry found.
* @retval others Pointer to the found key entry.
*/
T_LE_KEY_ENTRY *le_find_key_entry_v2(uint8_t *remote_bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_bd_type,
uint8_t *local_bd_addr, uint8_t local_bd_type);
/**
* @brief Find key entry by index.
*
* @param[in] idx Key entry index.
* @return p_entry Pointer to the found key entry.
* @retval null No entry found.
* @retval Others Pointer to the found key entry.
*/
T_LE_KEY_ENTRY *le_find_key_entry_by_idx(uint8_t idx);
/**
* @brief Get the bonded device count.
*
* Note: You can call this function after @ref le_gap_init is invoked.
*
* @return num Bonded device count.
*/
uint8_t le_get_bond_dev_num(void);
/**
* @brief Get the low priority bond device key entry.
*
* Note: You can call this function after @ref le_gap_init is invoked.
*
* @return p_entry Pointer to the found key entry.
* @retval null No entry found.
* @retval Others Pointer to the found key entry.
*/
T_LE_KEY_ENTRY *le_get_low_priority_bond(void);
/**
* @brief Get the high priority bond device key entry.
*
* Note: You can call this function after @ref le_gap_init is invoked.
*
* @return p_entry Pointer to the found key entry.
* @retval null No entry found.
* @retval others Pointer to the found key entry.
*/
T_LE_KEY_ENTRY *le_get_high_priority_bond(void);
/**
* @brief Make the specified bonded device with the high priority.
*
* NOTE: When the default value of @ref gap_config_local_addr_storage is true
* or @ref gap_config_local_addr_storage (true) has been configured,
* this function cannot be used if local device uses different local
* addresses to bond with the same remote device. In this situation,
* @ref le_set_high_priority_bond_v2 shall be called.
*
* @param[in] bd_addr Remote bluetooth device address.
* @param[in] bd_type Remote bluetooth device address type.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_set_high_priority_bond(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type);
/**
* @brief Make the specified bonded device with the high priority.
*
* @param[in] p_entry Pointer the key entry of the bonded device.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_set_high_priority_bond_v2(T_LE_KEY_ENTRY *p_entry);
/**
* @brief Resolve the specified bonded device.
*
* @param[in] unresolved_addr Unresolved remote bluetooth device address.
* @param[in,out] resolved_addr Resolved remote bluetooth device address.
* @param[in,out] resolved_addr_type Resolved remote bluetooth device address type.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*
* Example usage
* \code{.c}
void app_handle_authen_state_evt(uint8_t conn_id, uint8_t new_state, uint16_t status)
{
APP_PRINT_INFO1("app_handle_authen_state_evt:conn_id %d", conn_id);
switch (new_state)
{
...
case GAP_AUTHEN_STATE_COMPLETE:
{
APP_PRINT_INFO1("GAP_MSG_LE_AUTHEN_STATE_CHANGE:(GAP_AUTHEN_STATE_COMPLETE) status 0x%x",
status);
if (status == 0)
{
APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair success");
{
uint8_t addr[6];
T_GAP_REMOTE_ADDR_TYPE bd_type;
uint8_t resolved_addr[6];
T_GAP_IDENT_ADDR_TYPE resolved_bd_type;
le_get_conn_addr(conn_id, addr, &bd_type);
if (bd_type == GAP_REMOTE_ADDR_LE_RANDOM)
{
if (le_resolve_random_address(addr, resolved_addr, &resolved_bd_type))
{
APP_PRINT_INFO2("GAP_AUTHEN_STATE_COMPLETE: resolved_addr %s, resolved_addr_type %d",
TRACE_BDADDR(resolved_addr), resolved_bd_type);
}
else
{
APP_PRINT_INFO0("GAP_AUTHEN_STATE_COMPLETE: resolved addr failed");
}
}
}
}
else
{
APP_PRINT_INFO0("GAP_MSG_LE_AUTHEN_STATE_CHANGE pair failed");
}
}
break;
...
}
}
* \endcode
*/
bool le_resolve_random_address(uint8_t *unresolved_addr, uint8_t *resolved_addr,
T_GAP_IDENT_ADDR_TYPE *resolved_addr_type);
/**
* @brief Get the cccd information of the bonded device.
*
* @param[in] p_entry Pointer the key entry of the bonded device.
* @param[out] p_data Pointer to ccccd data to read.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*
* Example usage
* \code{.c}
void test(void)
{
T_GAP_REMOTE_ADDR_TYPE remote_addr_type;
uint8_t bd_addr[6];
uint8_t conn_id = 0;
uint8_t ccc_bits_count = 16;
T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
T_LE_KEY_ENTRY *p_entry = NULL;
if(le_get_conn_addr(conn_id, bd_addr, &remote_addr_type))
{
p_entry = le_find_key_entry(bd_addr, remote_addr_type);
if (p_entry)
{
if (le_get_cccd_data(p_entry, p_cccd_data))
{
APP_PRINT_INFO2("Get cccd data: len %d, data %s", p_cccd_data->data_length,
TRACE_BINARY(p_cccd_data->data_length, p_cccd_data->data));
}
}
}
os_mem_free(p_cccd_data);
}
* \endcode
*/
bool le_get_cccd_data(T_LE_KEY_ENTRY *p_entry, T_LE_CCCD *p_data);
/**
* @brief Generate a new bonded device information by APP.
*
* NOTE: When the default value of @ref gap_config_local_addr_storage is true
* or @ref gap_config_local_addr_storage (true) has been configured, this
* function cannot be used. In this situation, @ref le_gen_bond_dev_v2
* shall be called.
*
* @param[in] bd_addr Remote bluetooth device address.
* @param[in] bd_type Remote bluetooth device address type.
* @param[in] local_bd_type Local bluetooth device address type.
* @param[in] ltk_length LTK length.
* @param[in] p_ltk Pointer to LTK to write.
* @param[in] p_cccd Pointer to cccd data to write.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*
* Example usage
* \code{.c}
void test(void)
{
T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
uint8_t bd_addr[6] = {0x11,0x22,0x33,0x44,0x55,0x66};
uint8_t ltk_length = 16;
uint8_t ltk[16] = {0x0, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN;
uint8_t ccc_bits_count = 16;
T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
p_cccd_data->data_length = 4;
p_cccd_data->data[0] = 0x04;
p_cccd_data->data[1] = 0x00;
p_cccd_data->data[2] = 0x02;
p_cccd_data->data[3] = 0x00;
if(le_gen_bond_dev(bd_addr, remote_addr_type, GAP_LOCAL_ADDR_LE_PUBLIC,
ltk_length, ltk, key_type, p_cccd_data))
{
APP_PRINT_INFO0("Generate bond device success");
}
os_mem_free(p_cccd_data);
}
* \endcode
*/
bool le_gen_bond_dev(uint8_t *bd_addr, T_GAP_REMOTE_ADDR_TYPE bd_type,
T_GAP_LOCAL_ADDR_TYPE local_bd_type,
uint8_t ltk_length, uint8_t *p_ltk, T_LE_KEY_TYPE key_type, T_LE_CCCD *p_cccd);
/**
* @brief Generate a new bonded device information by APP.
*
* @param[in] remote_bd_addr Remote bluetooth device address.
* @param[in] remote_bd_type Remote bluetooth device address type.
* @param[in] local_bd_addr Local bluetooth device address.
* @param[in] local_bd_type Local bluetooth device address type.
* @param[in] ltk_length LTK length.
* @param[in] p_ltk Pointer to LTK to write.
* @param[in] p_cccd Pointer to cccd data to write.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*
* Example usage
* \code{.c}
void test(void)
{
T_GAP_REMOTE_ADDR_TYPE remote_addr_type = GAP_REMOTE_ADDR_LE_PUBLIC;
uint8_t remote_bd_addr[6] = {0x11,0x22,0x33,0x44,0x55,0x66};
uint8_t local_bd_addr[6] = {0x00,0x22,0x33,0x44,0x55,0x66};
uint8_t ltk_length = 16;
uint8_t ltk[16] = {0x0, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
T_LE_KEY_TYPE key_type = LE_KEY_UNAUTHEN;
uint8_t ccc_bits_count = 16;
T_LE_CCCD *p_cccd_data = os_mem_alloc(RAM_TYPE_DATA_ON, 4 + ccc_bits_count * 4);
p_cccd_data->data_length = 4;
p_cccd_data->data[0] = 0x04;
p_cccd_data->data[1] = 0x00;
p_cccd_data->data[2] = 0x02;
p_cccd_data->data[3] = 0x00;
if(le_gen_bond_dev_v2(remote_bd_addr, remote_addr_type, local_bd_addr, GAP_LOCAL_ADDR_LE_PUBLIC,
ltk_length, ltk, key_type, p_cccd_data))
{
APP_PRINT_INFO0("Generate bond device success");
}
os_mem_free(p_cccd_data);
}
* \endcode
*/
bool le_gen_bond_dev_v2(uint8_t *remote_bd_addr, T_GAP_REMOTE_ADDR_TYPE remote_bd_type,
uint8_t *local_bd_addr, T_GAP_LOCAL_ADDR_TYPE local_bd_type, uint8_t ltk_length,
uint8_t *p_ltk, T_LE_KEY_TYPE key_type, T_LE_CCCD *p_cccd);
#if F_BT_LE_PRIVACY_SUPPORT
/**
* @brief Save privacy information.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[in] p_privacy_info Pointer to privacy information to write.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_set_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info);
/**
* @brief Get privacy information.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[out] p_privacy_info Pointer to privacy information to read.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_get_privacy_info(T_LE_KEY_ENTRY *p_entry, T_LE_PRIVACY_INFO *p_privacy_info);
/**
* @brief Check the bonded device whether it is a privacy device.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @return Operation result.
* @retval true This bonded device is a privacy device.
* @retval false This bonded device is not a privacy device.
*/
bool le_check_privacy_bond(T_LE_KEY_ENTRY *p_entry);
#endif
/**
* @brief Get length of device bond information.
*
* @return Length of device bond information.
*/
uint16_t le_get_dev_bond_info_len(void);
/**
* @brief Get device bond information.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[in] p_data Pointer to bond information to read.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_get_dev_bond_info(T_LE_KEY_ENTRY *p_entry, uint8_t *p_data);
/**
* @brief Set device bond information.
*
* @param[in] length Length of device bond information.
* @param[in] p_data Pointer to bond information to write.
* @param[in,out] exist Indicate whether bond information of the device is existed.
* @return p_entry Pointer to the key entry.
* @retval null No entry, operation failure.
* @retval others Pointer to the key entry. If parameter exist is false, operation success. If parameter exist is true, bond information of the device is existed.
*/
T_LE_KEY_ENTRY *le_set_dev_bond_info(uint16_t length, uint8_t *p_data, bool *exist);
/**
* @brief Get maximum pairing information number that can be stored.
*
* NOTE: This function can be called after @ref le_gap_init is invoked.
*
* @return Maximum number of LE paired device information that can be stored.
*/
uint8_t le_get_max_le_paired_device_num(void);
/**
* @brief Get device information.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[out] p_data Pointer to bond information to read.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_get_dev_info(T_LE_KEY_ENTRY *p_entry, T_LE_DEV_INFO *p_info);
/**
* @brief Modify local LTK.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[in] key_length key length, Range: 7 to 16.
* @param[in] p_ltk Pointer to local ltk to save.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_set_local_ltk(T_LE_KEY_ENTRY *p_entry, uint8_t key_length, uint8_t *p_ltk);
/**
* @brief Erase CCCD except specific attribute handle.
*
* NOTE: This function can only be used for standby state (i.e., no link, not initiating, etc.).
*
* @param[in] handle_num Number of attribute handle of CCCD which will not be erased
* @param[in] p_handle Pointer to attribute handle of CCCD which will not be erased
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_clear_cccd_data(uint16_t handle_num, uint16_t *p_handle);
/**
* @brief Get remote device IRK information.
*
* @param[in] p_entry Pointer to the key entry of bonded device.
* @param[in] remote Read the remote IRK or the local IRK.
* @param[out] p_irk Pointer to IRK to read.
* @return Operation result.
* @retval true Operation success.
* @retval false Operation failure.
*/
bool le_get_dev_irk(T_LE_KEY_ENTRY *p_entry, bool remote, uint8_t *p_irk);
/** @} */ /* End of group GAP_LE_STORAGE_EXPORT_Functions */
/** @} */ /* End of group GAP_LE_STORAGE */
#ifdef __cplusplus
}
#endif
#endif /* FLASH_KEY_MGR_LE_H */