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.

How to Detect Invalid PIN During Pairing?



I am testing BT pairing using CC2564B and Bluetopia SDK 1.4R2.

The problem I am facing is in detecting when user enters an invalid PIN during pairing. I am using an Android phone to pair the device. If I enter invalid PIN from the Android phone, the connection doesn't get established as expected, but I haven't been able to find a way to identify that the PIN was invalid.

Until today, I was relying on the return value of GAP_Authentication_Response() in PINCodeResponse() (see below) , but found out a few minutes ago that its return value is not actually an indication of valid/invalid PIN. Based on this post, I tried to use GAP_Event_Callback() case atAuthenticationStatus. But this doesn't get called for some reason. Please let me know the right way to detect invalid PIN entry.


int PINCodeResponse(ParameterList_t *TempParam) { int Result; int ret_val; PIN_Code_t PINCode; GAP_Authentication_Information_t GAP_Authentication_Information; /* First, check that valid Bluetooth Stack ID exists. */ if(BluetoothStackID) { /* First, check to see if there is an on-going Pairing operation */ /* active. */ if(!COMPARE_BD_ADDR(CurrentRemoteBD_ADDR, NullADDR)) { /* Make sure that all of the parameters required for this */ /* function appear to be at least semi-valid. */ if((TempParam) && (TempParam->NumberofParameters > 0) && (TempParam->Params[0].strParam) && (BTPS_StringLength(TempParam->Params[0].strParam) > 0) && (BTPS_StringLength(TempParam->Params[0].strParam) <= sizeof(PIN_Code_t))) { /* Parameters appear to be valid, go ahead and convert the */ /* input parameter into a PIN Code. */ /* Initialize the PIN code. */ ASSIGN_PIN_CODE(PINCode, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); BTPS_MemCopy(&PINCode, TempParam->Params[0].strParam, BTPS_StringLength(TempParam->Params[0].strParam)); /* Populate the response structure. */ GAP_Authentication_Information.GAP_Authentication_Type = atPINCode; GAP_Authentication_Information.Authentication_Data_Length = (Byte_t)(BTPS_StringLength(TempParam->Params[0].strParam)); GAP_Authentication_Information.Authentication_Data.PIN_Code = PINCode; /* Submit the Authentication Response. */ Result = GAP_Authentication_Response(BluetoothStackID, CurrentRemoteBD_ADDR, &GAP_Authentication_Information); /* Check the return value for the submitted command for */ /* success. */ if(!Result) { /* Flag success to the caller. */ ret_val = 0; } else { ret_val = FUNCTION_ERROR; } /* Flag that there is no longer a current Authentication */ /* procedure in progress. */ ASSIGN_BD_ADDR(CurrentRemoteBD_ADDR, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); } else { ret_val = INVALID_PARAMETERS_ERROR; } } else { ret_val = FUNCTION_ERROR; } } else { /* No valid Bluetooth Stack ID exists. */ ret_val = INVALID_STACK_ID_ERROR; } return(ret_val); }

Excerpts from GAP_Event_Callback():

static void BTPSAPI GAP_Event_Callback(unsigned int BluetoothStackID, GAP_Event_Data_t *GAP_Event_Data, unsigned long CallbackParameter)
{
    int                               Result;
    int                               Index;
    BD_ADDR_t                         NULL_BD_ADDR;
    Boolean_t						 OOB_Data;
    Boolean_t                         MITM;
    GAP_IO_Capability_t               RemoteIOCapability;
    GAP_Inquiry_Event_Data_t         *GAP_Inquiry_Event_Data;
    GAP_Remote_Name_Event_Data_t     *GAP_Remote_Name_Event_Data;
    GAP_Authentication_Information_t  GAP_Authentication_Information;

    /* First, check to see if the required parameters appear to be       */
    /* semi-valid.                                                       */
    if ((BluetoothStackID) && (GAP_Event_Data))
    {
        /* The parameters appear to be semi-valid, now check to see what  */
        /* type the incoming event is.                                    */
        switch (GAP_Event_Data->Event_Data_Type)
        {
        case etInquiry_Result:
            break;

        case etInquiry_Entry_Result:
            break;

        case etAuthentication:
            /* An authentication event occurred, determine which type of*/
            /* authentication event occurred.                           */
            switch (GAP_Event_Data->Event_Data.GAP_Authentication_Event_Data->GAP_Authentication_Event_Type)
            {
            case atLinkKeyRequest:
                break;

            case atPINCodeRequest:
                break;

            case atAuthenticationStatus:
                /* An authentication status event occurred, display   */
                /* all relevant information.                          */
                BD_ADDRToStr(GAP_Event_Data->Event_Data.GAP_Authentication_Event_Data->Remote_Device, Callback_BoardStr);
                /* Flag that there is no longer a current             */
                /* Authentication procedure in progress.              */
                ASSIGN_BD_ADDR(CurrentRemoteBD_ADDR, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
                break;

            case atLinkKeyCreation:
                break;

            case atIOCapabilityRequest:
                break;

            case atIOCapabilityResponse:
                break;

            case atUserConfirmationRequest:
                break;

            case atPasskeyRequest:
                break;

            case atRemoteOutOfBandDataRequest:
                break;

            case atPasskeyNotification:
                break;

            case atKeypressNotification:
                break;

            default:
                break;
            }
            break;

        case etRemote_Name_Result:
            break;

        case etEncryption_Change_Result:
            break;

        default:
            break;
        }
    }
}

  • Hi , Your query has been assigned to BT expert. We will get back to you shortly
    Saurabh
  • Hi Unni,

    When the remote device initiates the pairing with Bluetopia, The GAP will only indicate that the authentication response was successfully sent to the remote device. If the remote device rejects the authentication, GAP layer of the BT stack will not notice the difference. But you can still look at the HCI layer callback to see this.

    /* Process the Event Data.                                        */
          switch(HCI_Event_Data->Event_Data_Type)
          {
             ...
    		 
    		 case etConnection_Complete_Event:
    		    if(HCI_Event_Data->Event_Data.HCI_Connection_Complete_Event_Data)
    			{
    			   if(HCI_Event_Data->Event_Data.HCI_Connection_Complete_Event_Data->Status == 0x05)
    			   {
    			      Display("HCI Event Authentication Failed. \r\n");
    			   }
    			}
    		    break;
             
             ...		 
             default:
                break;
          }

    If you add the above case to your HCI_Event_Callback, you will be able to get indication when the PINCode is wrong. 

    Note: If you reverse the roles, and initiate the pairing process from the Bluetopia, you will get "atAuhenticationStatus: 5 for <BD_ADDR of phone>" in the GAP callback when the remote device enters a wrong PIN code. No need to look at HCI callback in this case. The Authentication Status = 5 refers to the "#define HCI_ERROR_CODE_AUTHENTICATION_FAILURE 0x05" of the HCITypes.h.

    Best regards,

    Vihng

  • Thank you for the detailed reply and for saving my day again. :)