question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Device Name Characteristic (2A00) Write Access Denied - Windows

See original GitHub issue
  • bleak version: 0.14.3
  • Python version: 3.8.10
  • Operating System: Windows 10 Pro

Description

I am trying to use bleak to write to the device name 00002a00-0000-1000-8000-00805f9b34fb on a Nordic nrf52840. I can read and write to it using LightBlue, but on windows i keep getting the following errors when using the test script below.

bleak.exc.BleakError: Could not write value b'TEST' to characteristic 0002: Access Denied

The value is reported as writeable when i read it: [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb: (read,write) | Name: , Value: No Value

I think this is a similar error to this one.

I don’t think it’s an issue with the peripheral’s code, as the device name can be changed using the LightBlue app. Is this an issue with bleak/bleak-winrt, or am i doing something wrong?

What I Did

Script

#import bleak (https://pypi.org/project/bleak/)
"""
----------------
XPC Reader
----------------
Operation:
    1) Connects and displays services with read characteristics
    2) If Nordic DFU service is found, returns PASS

"""

import asyncio
import codecs

from bleak import exc
from bleak import BleakClient

DEVICE_NAME_UUID = "00002a00-0000-1000-8000-00805f9b34fb"
DEVICE_NAME_LABEL = "Device Name: "

async def run(address, num_attempts=10, debug=False):

    global result

    print('Connecting...')
    for i in range (num_attempts): # note, this for loop is to avoid the software failing connection issue
        print(f'attempt: {i}')
        try:
            print('Attempting connection')
            async with BleakClient(address) as client:
                print('Connnected')

                for service in client.services:
                    for char in service.characteristics:
                        if "read" in char.properties:
                            if (char.uuid == DEVICE_NAME_UUID):
                                print("Reading...\n")
                                data = await client.read_gatt_char(char.uuid)
                                print(DEVICE_NAME_LABEL,codecs.decode(data, 'UTF-8'))

                                try:
                                    value = bytes(await client.read_gatt_char(char.uuid))
                                except Exception as e:
                                    value = str(e).encode()
                                else:
                                    value = "No Value"
                                print(
                                    f"\t[Characteristic] {char.uuid}: ({','.join(char.properties)}) | Name: {char.description}, Value: {value} ")
                                for descriptor in char.descriptors:
                                    value = await client.read_gatt_descriptor(descriptor.handle)
                                    print(f"\t\t[Descriptor] {descriptor.uuid}: (Handle: {descriptor.handle}) | Value: {bytes(value)} ")

                for service in client.services:
                    for char in service.characteristics:
                        if "write" in char.properties:
                            if (char.uuid == DEVICE_NAME_UUID):
                                print('Writing...\n')
                                data = codecs.encode('TEST', 'UTF-8')
                                await client.write_gatt_char(DEVICE_NAME_UUID, data, response=False)
                                print(f'written: {data} to {DEVICE_NAME_UUID}')
            print('Written, breaking out of for loop')
            break
        except exc.BleakDBusError:
            print('\n>> Bleak ERROR: Software caused connection abort <<\n')
            continue

        if(i == (num_attempts-1)):
            print(f"No connection after {num_attempts} attempts: ABORTING program")
            quit()

    print('disconnecting')    
    await client.disconnect()
        

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    address = 'C7:4A:5E:FD:31:F2'

    asyncio.run(run(address))

Result

Connecting...
attempt: 0
Attempting connection
Connnected
Reading...

Device Name:  T
        [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb: (read,write) | Name: , Value: No Value 
Writing...

Traceback (most recent call last):
  File "c:/Users/ed.bisdee/OneDrive - Enerpac Tool Group/Documents/_code/enerpac_bluetooth_scan/lock_scripts/read_write_dev_name.py", line 84, in <module>
    asyncio.run(run(address))
  File "C:\Users\ed.bisdee\AppData\Local\Programs\Python\Python38\lib\asyncio\runners.py", line 44, in run        
    return loop.run_until_complete(main)
  File "C:\Users\ed.bisdee\AppData\Local\Programs\Python\Python38\lib\asyncio\base_events.py", line 616, in run_until_complete
    return future.result()
  File "c:/Users/ed.bisdee/OneDrive - Enerpac Tool Group/Documents/_code/enerpac_bluetooth_scan/lock_scripts/read_write_dev_name.py", line 62, in run
    await client.write_gatt_char(DEVICE_NAME_UUID, data, response=False)
  File "C:\Users\ed.bisdee\AppData\Local\Programs\Python\Python38\lib\site-packages\bleak\backends\winrt\client.py", line 617, in write_gatt_char
    _ensure_success(
  File "C:\Users\ed.bisdee\AppData\Local\Programs\Python\Python38\lib\site-packages\bleak\backends\winrt\client.py", line 102, in _ensure_success
    raise BleakError(f"{fail_msg}: Access Denied")
bleak.exc.BleakError: Could not write value b'TEST' to characteristic 0002: Access Denied

Here is the output of service_explorer.py

INFO:bleak.backends.winrt.client:Services resolved for BleakClientWinRT (C7:4A:5E:FD:31:F2)
INFO:__main__:Connected: True
INFO:__main__:[Service] 00001800-0000-1000-8000-00805f9b34fb (Handle: 1): Generic Access Profile
INFO:__main__:  [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb (Handle: 2):  (read,write), Value: b'T'
INFO:__main__:  [Characteristic] 00002a01-0000-1000-8000-00805f9b34fb (Handle: 4):  (read), Value: b'\x00\x00'
INFO:__main__:  [Characteristic] 00002a04-0000-1000-8000-00805f9b34fb (Handle: 6):  (read), Value: b'\x18\x00$\x00\x03\x00\x90\x01'
INFO:__main__:  [Characteristic] 00002aa6-0000-1000-8000-00805f9b34fb (Handle: 8):  (read), Value: b'\x01'
INFO:__main__:[Service] 00001801-0000-1000-8000-00805f9b34fb (Handle: 10): Generic Attribute Profile
INFO:__main__:[Service] 0000180a-0000-1000-8000-00805f9b34fb (Handle: 11): Device Information
INFO:__main__:  [Characteristic] 00002a29-0000-1000-8000-00805f9b34fb (Handle: 12):  (read), Value: b'MyCompany'
INFO:__main__:  [Characteristic] 00002a24-0000-1000-8000-00805f9b34fb (Handle: 14):  (read), Value: b'XXX-CONFIG:1'
INFO:__main__:  [Characteristic] 00002a25-0000-1000-8000-00805f9b34fb (Handle: 16):  (read), Value: b'0h'
INFO:__main__:  [Characteristic] 00002a27-0000-1000-8000-00805f9b34fb (Handle: 18):  (read), Value: b'REV-1'
INFO:__main__:  [Characteristic] 00002a26-0000-1000-8000-00805f9b34fb (Handle: 20):  (read), Value: b'9.1.4'
INFO:__main__:[Service] 0000180f-0000-1000-8000-00805f9b34fb (Handle: 22): Battery Service
INFO:__main__:  [Characteristic] 00002a19-0000-1000-8000-00805f9b34fb (Handle: 23):  (read,notify), Value: b'd'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 25): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:[Service] bd9d2df5-c6fe-4516-87cf-96e307626be4 (Handle: 26): Unknown
INFO:__main__:  [Characteristic] bd9d2df9-c6fe-4516-87cf-96e307626be4 (Handle: 27):  (read,notify), Value: b'\x06\x00'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 29): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 30): Characteristic Presentation Format) | Value: b'\x0e\x00\x00\x00\x00\x00\x00'
INFO:__main__:  [Characteristic] bd9d2dfb-c6fe-4516-87cf-96e307626be4 (Handle: 31):  (read,notify), Value: b'\x8b'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 33): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 34): Characteristic Presentation Format) | Value: b'\x01\x00\x00\x00\x00\x00\x00'
INFO:__main__:[Service] c730d649-5e58-5643-5444-f74d8b9ba87f (Handle: 35): Unknown
INFO:__main__:  [Characteristic] c730d64a-5e58-5643-5444-f74d8b9ba87f (Handle: 36):  (read,write), Value: b'00000000000000'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 38): Characteristic Presentation Format) | Value: b'\x19\x00\x00\x00\x00\x00\x00'
INFO:__main__:  [Characteristic] c730d64b-5e58-5643-5444-f74d8b9ba87f (Handle: 39):  (read,write), Value: b'1970-01-01T00:00:00Z'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 41): Characteristic Presentation Format) | Value: b'\x19\x00\x00\x00\x00\x00\x00'
INFO:__main__:[Service] f69f1e6b-5259-4dff-b77c-10e04eb2be96 (Handle: 42): Unknown
INFO:__main__:  [Characteristic] f69f1e70-5259-4dff-b77c-10e04eb2be96 (Handle: 43):  (read,notify), Value: b'\x00'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 45): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 46): Characteristic Presentation Format) | Value: b'\x01\x00\x00\x00\x00\x00\x00'
INFO:__main__:  [Characteristic] f69f1e6e-5259-4dff-b77c-10e04eb2be96 (Handle: 47):  (read,notify), Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 49): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 50): Characteristic Presentation Format) | Value: b'\x0e\x00\x00\x00\x00\x00\x00'
INFO:__main__:  [Characteristic] f69f1e6d-5259-4dff-b77c-10e04eb2be96 (Handle: 51):  (read,notify), Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 53): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 54): Characteristic Presentation Format) | Value: b'\x0e\x00\x00\x00\x00\x00\x00'
INFO:__main__:  [Characteristic] f69f1e6c-5259-4dff-b77c-10e04eb2be96 (Handle: 55):  (read,notify), Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 57): Client Characteristic Configuration) | Value: b'\x00\x00'
INFO:__main__:          [Descriptor] 00002904-0000-1000-8000-00805f9b34fb (Handle: 58): Characteristic Presentation Format) | Value: b'\x06\x00\x00\x00\x00\x00\x00'
INFO:__main__:[Service] 0000fe59-0000-1000-8000-00805f9b34fb (Handle: 59): Nordic Semiconductor ASA
INFO:__main__:  [Characteristic] 8ec90003-f315-4f60-9fb8-838830daea50 (Handle: 60):  (write,indicate), Value: None
INFO:__main__:          [Descriptor] 00002902-0000-1000-8000-00805f9b34fb (Handle: 62): Client Characteristic Configuration) | Value: b'\x00\x00'

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
jochenjagerscommented, Sep 13, 2022

I had a very similar problem while writing data to a Nordic UART service. I had many access denies errors when I started with bleak version 0.13 and after updating to 0.15 it change more to “The object is already closed” or “A method was called at an unexpected time” (don’t know the exact error messages as my system reported them in German) The problem for me was that the device kept updating the service list during service discovery. I added a gatt_services_changed listener to the WinRT client and started over with service discovery if it is was currently running or started a new discovery before accessing the services list the next time. The documentation of the GattServicesChanged event (https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothledevice.gattserviceschanged) says:

This event is raised when the remote device changes its services, or an unpaired device is disconnecting. All services are cleared because unpaired device services can’t be cached between connections. The object parameter in this event is null for every event that is raised. In your handler for this event, do the following in order to get the services available. Call BluetoothLEDevice.GetGattServicesAsync on the BluetoothLEDevice that’s passed to your handler. When calling GetGattServicesAsync, use the Cached option. This can be used to refresh the list of services and re-initialize the services on the device if they are gone.

For my device I get the event 11 times during the first service discovery and if I reload them after I got the event everything works as expected. I can open a PR in the next days with a suggestion how to deal with this issue.

0reactions
dlechcommented, Sep 22, 2022

Windows is protective of some well-known services/characteristics and won’t allow accessing them. Similarly, BlueZ hides the GAP Service completely, making the device name inaccessible. Furthermore, the device name displayed by the operating system may not be the same one as read by this characteristic - many OSes allow “changing the name” but it really means providing a local alias for the device and not actually writing that name to the device.

I think the ServicesChanged issue is a separate issue and we should start a new issue for that.

For the device name issue, I think we should have a property to get the device name instead of reading a characteristic. I don’t think writing the device name will be possible cross-platform. And as mentioned already, this name may be a local OS alias rather than the Device Name characteristic.

If you control the device firmware, you could add a custom attribute to update the device name if you really need to update the name on the device.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bluetooth LE Cannot write characteristic in "Device Information"
I have a problem with Bluetooth LE stack from windows. I made a WPF - application, which communicate with a BLE device. (using...
Read more >
setting device name with gatt characteristic (2a00) while using ...
Hello I am trying to use advertise my own data using gap_user_data and i would like to allocate all the available data bytes...
Read more >
Work with Device Characteristics and Descriptors - MathWorks
If multiple characteristics have the same name, differentiate between them using the UUID. In this example, the device has both standard and custom ......
Read more >
c# - BLE Using WinRT: Access Denied When Executing ...
For anyone who stumbles over the same stupid issue...Here's the solution: On Windows, using .NET Framework 4.6.1+ and the WinRT libraries ...
Read more >
Interferometer IMS5x00 - Micro-Epsilon
Access via Web Interface . ... Characteristics Distance Value and Analog Output . ... A 4.4.1.3 Object 1008h: Manufacturer's Device Name .
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found