aboutsummaryrefslogtreecommitdiff
path: root/inc/bluetooth/gap/gap_storage_le.h
blob: 7378e91a57876994ce2160c92470894a6f6477cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
/**
*********************************************************************************************************
*               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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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 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.
 *
 * @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   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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * <b>Example usage</b>
 * \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.
 *
 * @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.
 *
 * <b>Example usage</b>
 * \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);

#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);
/** @} */ /* End of group GAP_LE_STORAGE_EXPORT_Functions */
/** @} */ /* End of group GAP_LE_STORAGE */


#ifdef __cplusplus
}
#endif

#endif /* FLASH_KEY_MGR_LE_H */