This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2340R5: Implementation advice for intercepting BLE Pairing Request on TI CC2340

Part Number: CC2340R5

Hi TI Support Team,

I am reaching out on behalf of my customer, who is currently developing a project using the TI CC2340 (BLE5-Stack) for Medical Product.

They have a customized requirement regarding the BLE security and pairing process, and I would like to seek your advice on the official best practice for them.

[Application Scenario & Requirement]
The customer would like to maintain dynamic control over the pairing process. Their expected flow is as follows:
When a Phone sends a Pairing Request to the Device (CC2340), they want the Application layer on the Device to "intercept" this request. The App layer will then dynamically evaluate the current system status and decide to either:

  1. Accept the pairing: The device replies with a Pairing Response, allowing the pairing process to proceed normally.

  2. Reject the pairing: The device replies with an Error Code (e.g., Pairing Not Supported or other specific error codes) to abort the pairing immediately.

[Information Requested]
To help the customer achieve this dynamic interception and decision-making at the Application layer, could you please provide your insights on the following:

  1. Official Recommendation (Best Practice):
    What is TI's recommended approach to implement this on the CC2340? Are there standard APIs/Callbacks provided by the BLE stack for this specific purpose?

  2. Precautions & Potential Risks:
    Are there any specific considerations they should be aware of when introducing this dynamic interception mechanism? (e.g., potential impacts , state machine management, or compatibility issues with future SDK updates).

  3. Reference Resources:
    Do you have any reference code, example projects, or Application Notes that demonstrate a similar scenario?

Thank you for your time and support. I look forward to sharing your professional advice with the customer.

Best Regards,

  • Hi,

    Thank you for reaching out. The F3 SDK provides a few ways to handle pairing requests at the application level. You can reject all pairing vs start processing all pairing requests via the following APIs:

    // To REJECT all incoming pairing requests:
    uint8_t noPairing = GAPBOND_PAIRING_MODE_NO_PAIRING;  // 0x00
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &noPairing);
    
    // To ACCEPT incoming pairing requests again:
    uint8_t waitForReq = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;  // 0x01
    GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &waitForReq);

    The BLEAPPUtil framework does handle a lot of this for you. As pairing requests ar received, you will receive specific events in which you can decide to accept or reject the pairing attempt. This can be done via the GAP_TerminateAuth() function within the BLEAPPUTIL_PAIRING_STATE_STARTED event. The BLEAPPUTIL_PAIRING_STATE_STARTED event is received when a pairing requests comes in so you can then handle each requests individually. 

    I dont foresee any specific issues with this approach.

    I recommend starting with basic_ble and taking a look at the app_pairing.c file. Something like the following code snippet could be a good starting point (App_isSystemReadyForPairing would be your custom function for checking state)

            case BLEAPPUTIL_PAIRING_STATE_STARTED:
            {
                // Pairing request received — evaluate system state now
                if (!App_isSystemReadyForPairing())
                {
                    // Abort the pairing with a spec-compliant error code
                    GAP_TerminateAuth(pData->connHandle,
                                      SMP_PAIRING_FAILED_NOT_SUPPORTED);
                }
                break;
            }

    Best Regards,

    Jan

  • Hi TI Support Team

    Thanks for your response.

    Base on the post,

    How can I insert a check point between client(Pairing DHKey Check) and server(Pairing DHKey Check)?

    Best Wishes

    Baboo

  • Hi Baboo,

    Can you clarify what the goal of putting a checkpoint there is? There likely isn't a way to put a breakpoint at that exact point. You may be able to add a breakpoint after the pairing request is sent, but you will likely not be able to guarantee it has not executed before the server has responded.

    Best Regards,

    Jan

  • Hi Jan

    My goal is to avoid iphone bonding information not synchronize with peripheral

    Step as following

    1.[iphone] start security connection pairing(nRfconnect)

    2.[peripheral] user may have 2 choice (within BLE timeout period)

                          2.1 user wait a period for press button then confirm and SMP keep going,save bonding information          ,finish connection

                          2.2 user wait a period for press button then reject    and SMP reject         ,NOT save bonding information ,maybe disconnect

    Step2 need to be checked before bonding information generated,otherwise iphone save it,but peripheral Not save it will cause reconnection rejected.

    Best Wishes

    Baboo

  • Hi Baboo,

    Apologies for the delay. As the pairing events are received on the CC2340R5 side, you may reject the pairing which will cause the iPhone to not save the bond. 

    Best Regards,

    Jan

  • Hi Jan,

    Thank you for your previous response.

    We are following up on this thread on behalf of Baboo to ensure we have a clear understanding of the implementation details for their upcoming project.

    Baboo is currently in the important stages of evaluating the CC2340R5 for a new design.

    The ability to reliably manage the pairing process and ensure bonding synchronization is a critical requirement for their product’s user experience. 

    If we can confirm that this "Wait-and-Confirm" flow is fully supported and solvable on the F3 Stack, the CC2340R5 will be formally evaluated for adoption in this new project.

    To help us reach a conclusion, could you please provide more specific technical guidance on the following:

    1. The Interception Point: Within the GapBondMgr (e.g., via pairStateCB), which event allows the application to intercept the pairing request before any bonding data is generated or committed to the NV memory?

    2. Holding the SMP Process: What is the recommended approach to "pause" the pairing process while waiting for a physical button press? It is essential that the connection remains stable during this period (before the SMP timeout).

    3. Correct API Usage: Once the user provides manual confirmation via a button press, which API should be used to resume and either "Accept" or "Reject" the process? For the F3 Stack, is GAPBondMgr_PasscodeRsp the intended way to handle this?

    If you could provide a brief code snippet or point us to a relevant section in the basic_ble example, it would greatly accelerate Baboo’s evaluation process.

    We appreciate your expertise and look forward to your guidance, which will be instrumental in our platform selection.

    Best Regards,

    Mike

  • Hi Jan, 

    I would greatly appreciate any guidance or comment on this thread.

    Thank you so much for your time and continuous support!

    Best Regards,

    Mike

  • Hi Jan

    May need more details regarding below two points, would you give more descriptions, thanks!

    1. The Pause Mechanism: How to maintain the connection and prevent timeouts while the peripheral is waiting for a physical button press to confirm the pairing.
    2. Specific API Commands: Which exact APIs should be called to resume, accept, or reject the pairing process after the manual intervention.
  • Hi,

    Apologies for the delay. See below for some information regarding the questions asked:

    The Interception Point: Within the GapBondMgr (e.g., via pairStateCB), which event allows the application to intercept the pairing request before any bonding data is generated or committed to the NV memory?

    BLEAPPUTIL_PAIRING_STATE_STARTED is the correct event. It is dispatched from gapbondmgr.c before the Pairing Response is sent, which is the earliest possible interception point where nothing has been written to NV. For reference, NV is committed only when BLEAPPUTIL_PAIRING_STATE_BOND_SAVED fires, which is the last event in the pairing sequence

    Holding the SMP Process: What is the recommended approach to "pause" the pairing process while waiting for a physical button press? It is essential that the connection remains stable during this period (before the SMP timeout).

    The correct mechanism for a wait-and-confirm flow is the passcode callback (BLEAPPUTIL_PASSCODE_TYPE handler). The stack invokes this callback during the key-exchange phase which is after Pairing Request/Response but before pairing completes and before any NV write. Critically, the stack waits indefinitely at this point until GAPBondMgr_PasscodeRsp() is called, so the connection stays up while the user interacts.

    To trigger the passcode callback, configure IO capabilities to a mode that requires user interaction. For a simple button-confirm flow on the peripheral, GAPBOND_IO_CAP_DISPLAY_YES_NO negotiates Numeric Comparison with iOS (LE Secure Connections), which is the recommended approach for a medical product. GAPBOND_IO_CAP_KEYBOARD_ONLY is an alternative (Passkey Entry).

    In SysCfg, make sure to set your IO capabilities to allow for inputs and display. In the passcode callback: do not call GAPBondMgr_PasscodeRsp() directly. Post an event to your application task and return. The app task then waits for the GPIO button event before calling GAPBondMgr_PasscodeRsp(). The SMP protocol has a 30-second timeout (GAP_PARAM_SM_TIMEOUT, default 30,000 ms), so the button press must occur within that window.

    Correct API Usage: Once the user provides manual confirmation via a button press, which API should be used to resume and either "Accept" or "Reject" the process? For the F3 Stack, is GAPBondMgr_PasscodeRsp the intended way to handle this?

    Yes, GAPBondMgr_PasscodeRsp() is the intended API for this flow.

    • Accept (user presses confirm): GAPBondMgr_PasscodeRsp(connHandle, SUCCESS, numComparison) — pass pData->numComparison if Numeric Comparison is active; pass 0 if Passkey Entry with a fixed code.
    • Reject (user presses reject, or SMP timeout): GAPBondMgr_PasscodeRsp(connHandle, SMP_PAIRING_FAILED_PASSKEY_ENTRY_FAILED, 0

    When you reject via GAPBondMgr_PasscodeRsp with a failure status, the stack sends an SMP Pairing Failed PDU to the iPhone. The iPhone should not save any bond record. This directly addresses Baboo's synchronization concern: since pairing never completes, neither side has bonding data.