This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bonding issue in SDK11 with ANCS

Hi I am using SDK11 with S130, NRF51822 that using ANCS and facing bonding problems after reach the max bonds. Reference to nRF51-ble-peripheral-bond-handling example, I use the ble_app_ancs_c project example and add app_bond.c and app_bond.h to the project.

in main.c add:

#include "app_bond.h"
#include "nrf_nvic.h"
static app_bond_table_t                 m_app_bond_table;   

In device_manager_int(), add the followings:

{
...

app_bond_init(&m_app_bond_table);
    
    for(uint8_t i = 0; i < DEVICE_MANAGER_MAX_BONDS; i++)
    {
        printf("[APP][ID: %d], Application context : %08X\r\n",m_app_bond_table.device_id[i],(unsigned int) m_app_bond_table.app_bond_cnt[i]);
    }

}

in device_manager_evt_handler add the followings:

{

    static bool device_delete_all_started;
    
    // Recovery in the event of DM_DEVICE_CONTEXT_FULL
    if(event_result == DM_DEVICE_CONTEXT_FULL)
    {
        /* Clear all devices from the bond table*/ 
        err_code = dm_device_delete_all(&m_app_handle);
        APP_ERROR_CHECK(err_code);
        
        device_delete_all_started = true;
             
    }
    else
    {
        APP_ERROR_CHECK(event_result);   
    }
    
    if (p_evt->event_id == DM_EVT_DEVICE_CONTEXT_STORED)
    {
        table_index_t table_index;
        
        //Find first and last bond created from m_bond_index_table 
        app_bond_find(&m_app_bond_table,&table_index);
        
		//Increment counter if a new bond was created
        if(!(table_index.mr_cnt_val >= m_app_bond_table.app_bond_cnt[p_handle->device_id]))
        {
           table_index.mr_cnt_val++;
           m_app_bond_table.app_bond_cnt[p_handle->device_id] = table_index.mr_cnt_val;
        }
                
        //Delete first created bond if bond table is full 
        if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1)
             && (table_index.lr_cnt_val != NO_APP_CONTEXT))
          {
                uint32_t err_code;
                dm_handle_t device;
                
                device.appl_id = 0;
                    
                m_app_bond_table.app_bond_cnt[table_index.lr_index]=NO_APP_CONTEXT; 
                device.device_id = m_app_bond_table.device_id[table_index.lr_index];
                    
                err_code = dm_device_delete(&device); 
                APP_ERROR_CHECK(err_code);
                    
          }   
                
        //Update the app context for new device
        app_bond_update_context(&m_app_bond_table,p_handle); 
        
    }
    else if (p_evt->event_id ==DM_EVT_DEVICE_CONTEXT_DELETED)
    {
        
         /* Wait for all devices to be cleared before perfoming a sys reset */ 
         if(device_delete_all_started && (p_handle->device_id == DEVICE_MANAGER_MAX_BONDS -1))
         {
             err_code = sd_nvic_SystemReset();
             APP_ERROR_CHECK(err_code);
         }
         
    }

}

Disable whitelist in advertising_init(): options.ble_adv_whitelist_enabled = BLE_ADV_WHITELIST_DISABLED ;

In device_manager_peripheral.c

#define DEVICE_MANAGER_MAX_BONDS         4
#define DEVICE_MANAGER_APP_CONTEXT_SIZE    4

Then, I compile and run the program. I bond and remove the bonding with a iPhone over 4 times. ANCS works perfectly. Then I bond this to another iPhone, There is no ANCS response anymore. Open and close the bluetooth setting in iPhone is also same. it stop at notification enable but no ancs:

DB]: Discovery of service with UUID 0xf431 completed with success for Connectionhandle 0
[ANCS]: Database Discovery handler called with event 0x0
[ANCS]: Control Point Characteristic found.

[ANCS]: Notification point Characteristic found.

[ANCS]: Data Source Characteristic found.

[ANCS]: Data Source Characteristic found.

[ANCS]: Control Point Characteristic found.

Apple Notification Service discovered on the server.
[ANCS]: Enable Notification Source notifications. writing to handle: 31 

[ANCS]: Enable Data Source notifications. Writing to handle: 34 

Notifications Enabled.

this project is attached. ble_app_ancs_c_try3.zip

It seems the bonding have some problem when it is over the maximum value. I repeat the above procedure in sdk10, it works perfectly. Is there anything I have to add in sdk11 in order to work perfectly?

Thank you.

  • Hi,

    Could you explain this "Then I bond this to another iPhone, There is no ANCS response anymore. " ?

    There is no ANCS on the another iPhone or no ANCS on the first iPhone ?

    If you reach the maximum 4 bond, and you bond with another phone, the program will trigger DM_DEVICE_CONTEXT_FULL event and erase all bond. This explain why you can't connect to the first iPhone.

  • There is always ANCS on the first iPhone but no ANCS on another iPhone after reaching maximum bond. The SDK11's original ANCS example has the same phenomenon. If using SDK10's ANCS original example, when it reach the maximum 4 bond, it will never receive any ANCS again until erase and flash the program on the chip. As I add app_bond.c like nRF51-ble-peripheral-bond-handling example, it will never trigger DM_DEVICE_CONTEXT_FULL. Because the code will delete the last bond when DEVICE_MANAGER_MAX_BONDS-1 . It works in SDK10 but fail in SDK11.

  • Hi Chapman,

    Sorry I didn't notice the behavior of the example on github is to erase bond when it reach DEVICE_MANAGER_MAX_BONDS-1.

    Could you check what happens when you get DM_EVT_DEVICE_CONTEXT_STORED event, and reach DEVICE_MANAGER_MAX_BONDS-1 of bond (in this case 3) ? Do you see the code execute what it supposed to do of erasing the oldest bond ?

    If you have a sniffer , you can check if you can bond with the last central (the new phone) and if ANCS is transferred.

  • Actually, is is mentioned in github.com/.../nRF51-ble-peripheral-bond-handling that "The example always keeps one block free for a new device to be added, so make sure to adjust DEVICE_MANAGER_MAX_BONDS to desired number of bonds + 1." and //Delete first created bond if bond table is full if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1) However , it is checked in "if (p_evt->event_id == DM_EVT_DEVICE_CONTEXT_STORED)" and delete first created bond if bond table is full
    if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1) ..... This code is seen to be executed when it reach DEVICE_MANAGER_MAX_BONDS-1.

    I have a nrf51 dongle but I don't know how to use sniffer to check the bonding between my device with iphone. Is there any tutorial about that?

  • The tutorial is in the youtube introduction in the page I pointed to.

    I don't really get what you meant in your comment. You said if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1) is executed, meaning dm_device_delete(&device); is called, and it should free up one space in the database, and you should be able to bond with the next device.

    Could you check why it couldn't ?

Related