How to code Central Bonding?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi! I'm working on a project of an IAS that requires Bonding first. But my peer device is another BLE chip (example, I'm using dongle for this). Also, there will be an automatic connection between the two device through CyBle_GapcConnectDevice(); Moreover, I have fixed a passkey using CyBle_GapFixAuthPassKey(1, USER_PASSKEY);.

I have integrated Bonding on the IAS. I require a code that will write a passkey to the IAS. What events do I need and functions? Thanks!

0 Likes
1 Solution
Anonymous
Not applicable

I'm using no IO for my scenario; I setup the unit to bond to the first device that connects to it when a button is triggered, and once bonded it will only allow that bonded device to connect. Kind of like a permanent pairing between a garage door remote and the garage door controller.

Referring to my first comment:

The CYBLE_EVT_GAP_AUTH_FAILED, CYBLE_EVT_GAP_AUTH_COMPLETE, CYBLE_EVT_GAP_AUTH_REQ events should occur for either side of the connection

If you do a project keyword search for the event itself, you should find references to it's declaration, use, and documentation. The documentation in the comments are pretty thorough for explaining what actions can cause what events, and what they mean/do.

If you right-click on the BLE component in topdesign.cysch, and select "Open API Documentation" it will open a help file that contains all of the documentation for the various events, ble functions, etc. I suggest looking here first to read up on what the functions/events do.

I've attached a screenshot of the help files below.

CENTRAL

     if(peripheralFound)

     {

          CyBle_GapcConnectDevice(&connectPeriphDevice);

          // The Central will try to connect? Should I change this?

     }

This looks fine. The flow of the code for connecting and accessing would be: find peripheral (or use saved address) -> connect to device -> authenticate/encrypt -> read values -> disconnect, or do other things

PERIPHERAL - needs authentication

    case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:

          // Is this the right event after Central invoked function above?

          // Or when even other device tries to connect, like using CySmart

        (void) CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

        break;

Unfortunately, this event is only fired when you call the function CyBle_GattcStartDiscovery(), so unless you are calling that in code somewhere it won't fire upon connection.

On successful connection, the following events are generated at the GAP Central device (as well as the GAP Peripheral device), in the following order.

  • CYBLE_EVT_GATT_CONNECT_IND
  • CYBLE_EVT_GAP_DEVICE_CONNECTED - If the device connects to a GAP Central and Link Layer Privacy is disabled in component customizer.
  • CYBLE_EVT_GAP_ENHANCE_CONN_COMPLETE - If the device connects to a GAP Central and Link Layer Privacy is enabled in component customizer.
  • CYBLE_EVT_GAP_DEVICE_CONNECTED

So, you would probably want to trigger the CyBle_GapAuthReq() when the event CYBLE_EVT_GAP_DEVICE_CONNECTED occurs.

(Note these events will occur when any device connects)

After this at the CENTRAL

        case CYBLE_EVT_GAP_AUTH_REQ:

            CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

            // Am I still going there? Haha

            break;

This looks good, the event should fire when the peripheral requests authentication.

After this, you would just do the authentication handshake/procedure to correctly verify that the two devices connected together are the two devices that you want connected together, and then go to accessing data values for the application to use.

View solution in original post

6 Replies
Anonymous
Not applicable

I have this on my Peripheral:

    case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:

        /* Server is now discovered */

        /* Send authentication request to peer device */

        (void) CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

        break;

And this on my Central:

        case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:

            CyBle_GapAuthPassKeyReply(cyBle_connHandle.bdHandle, USER_PASSKEY, CYBLE_GAP_ACCEPT_PASSKEY_REQ);

            printf("/r/n I'm in Mofo. /r/n");

            break;

But seems not to work yet...

0 Likes
Anonymous
Not applicable

On the peripheral you will also need to handle the events:

CYBLE_EVT_GAP_AUTH_REQ: I am checking a state and then calling the CyBle_GapAuthReq() here, but I do not remember why I did that in the code. This might be the event where passkeys are entered/generated/displayed, but I'm not using passkeys for my application, so take that under advisement

CYBLE_EVT_GATTC_ERROR_RSP: Insufficient authentication or encryption required for reading an attribute will fire this.

CYBLE_EVT_GAP_AUTH_COMPLETE: If authentication is successful

CYBLE_EVT_GAP_AUTH_FAILED: If authentication fails

Anonymous
Not applicable

My Peripheral will be the one to send an Authentication Request.

I also modified the IAS, so in my code there will be

CENTRAL

     if(peripheralFound)

     {

          CyBle_GapcConnectDevice(&connectPeriphDevice);

          // The Central will try to connect? Should I change this?

     }

PERIPHERAL - needs authentication

    case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:

          // Is this the right event after Central invoked function above?

          // Or when even other device tries to connect, like using CySmart

        (void) CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

        break;

After this at the CENTRAL

        case CYBLE_EVT_GAP_AUTH_REQ:

            CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

            // Am I still going there? Haha

            break;

Also at this moment, a passkey is required.

I don't know what the Peripheral is in what event right now.

But in my CENTRAL, I added:

        case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:

            CyBle_GapAuthPassKeyReply(cyBle_connHandle.bdHandle, USER_PASSKEY,                CYBLE_GAP_ACCEPT_PASSKEY_REQ);

            printf("/r/n I'm in Mofo. /r/n");

            break;

I haven't integrated your first comment because I'm unsure where to put those event returns.

And, are you using anything instead of passkeys?

Also, I'm just trying to do a private connection between two devices, wherein in the Peripheral no other devices can connect to it but only the Central of it. Also, a secured connection. Do you suggest something else for this?

Thanks

0 Likes
Anonymous
Not applicable

I'm using no IO for my scenario; I setup the unit to bond to the first device that connects to it when a button is triggered, and once bonded it will only allow that bonded device to connect. Kind of like a permanent pairing between a garage door remote and the garage door controller.

Referring to my first comment:

The CYBLE_EVT_GAP_AUTH_FAILED, CYBLE_EVT_GAP_AUTH_COMPLETE, CYBLE_EVT_GAP_AUTH_REQ events should occur for either side of the connection

If you do a project keyword search for the event itself, you should find references to it's declaration, use, and documentation. The documentation in the comments are pretty thorough for explaining what actions can cause what events, and what they mean/do.

If you right-click on the BLE component in topdesign.cysch, and select "Open API Documentation" it will open a help file that contains all of the documentation for the various events, ble functions, etc. I suggest looking here first to read up on what the functions/events do.

I've attached a screenshot of the help files below.

CENTRAL

     if(peripheralFound)

     {

          CyBle_GapcConnectDevice(&connectPeriphDevice);

          // The Central will try to connect? Should I change this?

     }

This looks fine. The flow of the code for connecting and accessing would be: find peripheral (or use saved address) -> connect to device -> authenticate/encrypt -> read values -> disconnect, or do other things

PERIPHERAL - needs authentication

    case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:

          // Is this the right event after Central invoked function above?

          // Or when even other device tries to connect, like using CySmart

        (void) CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

        break;

Unfortunately, this event is only fired when you call the function CyBle_GattcStartDiscovery(), so unless you are calling that in code somewhere it won't fire upon connection.

On successful connection, the following events are generated at the GAP Central device (as well as the GAP Peripheral device), in the following order.

  • CYBLE_EVT_GATT_CONNECT_IND
  • CYBLE_EVT_GAP_DEVICE_CONNECTED - If the device connects to a GAP Central and Link Layer Privacy is disabled in component customizer.
  • CYBLE_EVT_GAP_ENHANCE_CONN_COMPLETE - If the device connects to a GAP Central and Link Layer Privacy is enabled in component customizer.
  • CYBLE_EVT_GAP_DEVICE_CONNECTED

So, you would probably want to trigger the CyBle_GapAuthReq() when the event CYBLE_EVT_GAP_DEVICE_CONNECTED occurs.

(Note these events will occur when any device connects)

After this at the CENTRAL

        case CYBLE_EVT_GAP_AUTH_REQ:

            CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);

            // Am I still going there? Haha

            break;

This looks good, the event should fire when the peripheral requests authentication.

After this, you would just do the authentication handshake/procedure to correctly verify that the two devices connected together are the two devices that you want connected together, and then go to accessing data values for the application to use.

Anonymous
Not applicable

I see. My peripheral though is a GATT server so I can't use CyBle_GattcStartDiscovery(). So Authentication request only works for Client? Used the example project for BLE_Bonding.

0 Likes
Anonymous
Not applicable

Only the Client can start the authentication request iirc; If the peripheral uses the same function, it will merely fire an event on the Client indicating that the peripheral wants the client to start authentication, but doesn't actually start authentication right then.

I believe in the example program, the example central code calls cyble_gattcstartdiscovery(), and thus it would fire. But, unless you are calling that function in your central code you are working on, the event will not fire 😕

Try calling the authentication request/start upon device connection:

  • CYBLE_EVT_GAP_DEVICE_CONNECTED
0 Likes