UWP BLE not working for authenticated attributes
I can't write to the CCCD on a BLE device that has the authentication flag enabled on the CCCD
Universal Windows Platform (UWP)
-
Corby Wilson 0 Reputation points
2024-07-31T00:32:20.31+00:00 Ok, now the post works.
I have a BLE device where one of the characteristics has[NOTIFY|AUTHENTICATE]
flags enabled.
I want to write to the CCCD but I get a GattProtocolError.InsufficientAuthentication error when writing.
Pairing doesn't workCustom Pairing doesn't work.
How do I get the OS to recognize that it needs to enable authentication when talking to the CHAR?
Sample Code:
def example(addr: int): device = await BluetoothLEDevice.from_bluetooth_address_async(int(self.info.addr)) svc_token = device.add_gatt_services_changed(self._on_services_changed) with await GattSession.from_device_id_async(device.bluetooth_device_id) as session: session_status_changed_token = session.add_session_status_changed(self._on_session_status_changed) mtu_changed_token = session.add_max_pdu_size_changed(self._on_mtu_changed) await self._discover_services(device) await asyncio.sleep(1) # Find my custom char with NOTIFY chars = [char for cid, char in self._chars.items() if cid < 0x100 and char.characteristic_properties & GattCharacteristicProperties.NOTIFY] char = chars[0] #char.protection_level = GattProtectionLevel.AUTHENTICATION_REQUIRED <-- does NOT work! desc = self._handles[char.attribute_handle + 2] #desc.protection_level = GattProtectionLevel.AUTHENTICATION_REQUIRED <-- ditto pe = await self._desc_write(desc, b'\x01\x00') if pe == GattProtocolError.insufficient_authentication: di = await self.pair(device.device_id) await asyncio.sleep(1) del di pe = await self._desc_write(desc, b'\x01\x00') session.remove_max_pdu_size_changed(mtu_changed_token) session.remove_session_status_changed(session_status_changed_token) device.remove_gatt_services_changed(svc_token)
-
Junjie Zhu - MSFT 17,816 Reputation points • Microsoft Vendor
2024-07-31T03:29:45.1033333+00:00 Hi @Corby Wilson ,
Welcome to Microsoft Q&A!
Sorry, we currently only support issues related to using the BLE API in UWP. Your project is written in Python, and it's not a UWP project.
Thank you.
-
Corby Wilson 0 Reputation points
2024-08-01T03:19:32.3933333+00:00 Pardon me. Let me change the color of the paint in my bucket:
using System; using Windows.Devices.Bluetooth; using Windows.Devices.Enumeration; using Windows.Devices.Bluetooth.GenericAttributeProfile; using System.Reflection.PortableExecutable; class Program { static async Task Main(string[] args) { string address = "D2:12:E2:18:78:32"; BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(ulong.Parse(address.Replace(":", ""), System.Globalization.NumberStyles.HexNumber)); bleDevice.GattServicesChanged += (sender, args) => Console.WriteLine($"GattServicesChanged: {args}"); GattSession gattSession = await GattSession.FromDeviceIdAsync(bleDevice.BluetoothDeviceId); gattSession.SessionStatusChanged += (sender, args) => Console.WriteLine($"SessionStatusChanged: {args}"); gattSession.MaxPduSizeChanged += (sender, args) => Console.WriteLine($"MaxPduSizeChanged: {args}"); Dictionary<int, Object> handles = await Device_DiscoverServices(bleDevice); var characteristicsWithNotify = handles.Values .Where(obj => obj is GattCharacteristic characteristic && characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify)) .Cast<GattCharacteristic>() .ToList(); bleDevice.DeviceInformation.Pairing.Custom.PairingRequested += (sender, args) => args.Accept(); DevicePairingResult pairingResult = await bleDevice.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ConfirmOnly); if (pairingResult.Status == DevicePairingResultStatus.Paired) { Console.WriteLine("Device paired successfully"); } else { Console.WriteLine($"Failed to pair with device: {pairingResult.Status}"); } foreach (var characteristic in characteristicsWithNotify) { ushort uuid16 = (ushort)(characteristic.Uuid.ToByteArray()[0] | (characteristic.Uuid.ToByteArray()[1] << 8)); string uuid16String = uuid16.ToString("X4"); Console.WriteLine($"Characteristic with notify property: {characteristic.Uuid}:{uuid16String}"); if (uuid16 < 100) { try { GattCommunicationStatus ret = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); if (ret != GattCommunicationStatus.Success) { Console.WriteLine($"Failed to write client characteristic configuration descriptor: {ret}"); } else { Console.WriteLine("Successfully wrote client characteristic configuration descriptor"); } } catch (Exception e) { Console.WriteLine($"Failed to write client characteristic configuration descriptor: {e}"); } } } } private static async Task<Dictionary<int, Object>> Device_DiscoverServices(BluetoothLEDevice bleDevice) { Dictionary<int, Object> handles = new Dictionary<int, Object>(); GattDeviceServicesResult result = await bleDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached); if (result.Status != GattCommunicationStatus.Success) { Console.WriteLine($"Failed to get GATT services: {result.Status}"); return handles; } foreach (GattDeviceService service in result.Services) { Console.WriteLine($"Service: {service.Uuid}"); handles.Add(service.AttributeHandle, service); GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached); if (characteristicsResult.Status != GattCommunicationStatus.Success) { Console.WriteLine($"Failed to get characteristics for service {service.Uuid}"); continue; } foreach (GattCharacteristic characteristic in characteristicsResult.Characteristics) { Console.WriteLine($" Characteristic: {characteristic.Uuid}"); handles.Add(characteristic.AttributeHandle, characteristic); GattDescriptorsResult descriptorsResult = await characteristic.GetDescriptorsAsync(BluetoothCacheMode.Uncached); if (descriptorsResult.Status != GattCommunicationStatus.Success) { Console.WriteLine($"Failed to get descriptors for characteristic {characteristic.Uuid}"); continue; } foreach (GattDescriptor descriptor in descriptorsResult.Descriptors) { Console.WriteLine($" Descriptor: {descriptor.Uuid}"); handles.Add(descriptor.AttributeHandle, descriptor); } } } return handles; } }
-
Junjie Zhu - MSFT 17,816 Reputation points • Microsoft Vendor
2024-08-01T06:35:50.0266667+00:00 Hi @Corby Wilson ,
Thank you for the code. What results did you get when running this code? How is it different from what you expected?
Sign in to comment