UWP BLE not working for authenticated attributes

Corby Wilson 0 Reputation points
2024-07-31T00:28:15.77+00:00

I can't write to the CCCD on a BLE device that has the authentication flag enabled on the CCCD

Developer technologies | Universal Windows Platform (UWP)
{count} votes

1 answer

Sort by: Most helpful
  1. Harry Vo (WICLOUD CORPORATION) 240 Reputation points Microsoft External Staff
    2025-07-07T04:14:09.4766667+00:00

    Hi @Corby Wilson ,

    The problem you are encountering is relating to authentication sequence. You are getting GattProtocolError.InsufficientAuthentication because the connection between your app and the BLE device is not using authenticated encryption. This prevents you from writing to the Client Characteristic Configuration Descriptor (CCCD).

    To resolve this, avoid using custom pairing. Instead, use the default pairing API with DevicePairingProtectionLevel.EncryptionAndAuthentication, which allows the OS to select a stronger authentication method (e.g., MITM) if the device requires it:

    //Instead of using custom pairing like this:
    bleDevice.DeviceInformation.Pairing.Custom.PairingRequested += ... 
    await bleDevice.DeviceInformation.Pairing.Custom.PairAsync(...);
    
    //Try using default pairing
    if (!bleDevice.DeviceInformation.Pairing.IsPaired) 
    {     
    	var result = await bleDevice.DeviceInformation.Pairing.PairAsync
    					(DevicePairingProtectionLevel.EncryptionAndAuthentication);     
    	if (result.Status == DevicePairingResultStatus.Paired)       
    		Console.WriteLine("Successfully paired with authentication");     
    	else         
    		Console.WriteLine($"Pairing failed: {result.Status}"); 
    }
    

    Once pairing is successful, dispose and recreate the BluetoothLEDevice object. This ensures the connection is reestablished with the correct security level:

    // After pairing
    bleDevice.Dispose();
    bleDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(...);
    

    This is because when you paired a BLE device using PairAsync, it updates the bonding/ security credentials at the OS level but any existing connection to the device does not automatically renegotiate the connection using the updated security level. So, to refresh this we can reestablished a newer connection.

    After that, try writing to the CCCD again:

    await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync
    (GattClientCharacteristicConfigurationDescriptorValue.Notify);
    

    Optional: If the EncryptionAndAuthentication fails, you can try the others:

    DevicePairingProtectionLevel[] levels = 
    {
    	DevicePairingProtectionLevel.EncryptionAndAuthentication,
    	DevicePairingProtectionLevel.Authentication,     
    	DevicePairingProtectionLevel.Encryption
    };
    

     If you run into further issues, feel free to ask for more details!

    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.