0

I have a respberry server and a windows client, both implemented in Python. The server transmits a BLE signal like a iBeacon signal.

Here is the code of the server:

import time

from bluetooth.ble import BeaconService

service = BeaconService()

uuid = "11111111-2222-3333-4444-555555555555"
major = 2   # 1 - 65535
minor = 1   # 1 - 65535
txpower = 1
interval = 200

service.start_advertising(uuid, major, minor, txpower, interval)

try:
    time.sleep(300)
    service.stop_advertising()

except KeyboardInterrupt:
    print("cancelled")

finally:
    service.stop_advertising()

print("Done.")

This code is working fine. I checked by installing an android app and I could find the device with that information.

Now I need to get that information in the windows client. In the windows client I'm using bleak library.

I have the following code to scan for beacon devices:

import asyncio
from bleak import discover

async def run():
    devices = await discover()
    for d in devices:
        #if d.address == "B8:27:EB:03:5A:D6":
        print(d.address, d.name, d.metadata, d.rssi)            

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

The problem is when I check the console, I dont see the major, minor and UUID information:

There are showed other devices and I can see in one of them that the UUID is readable. What I'm doing wrong here? Is bleak impossible to get the information I want? (minor, major) or am I transmitting in the wrong way? I dont think so because the mobile app is reading fine. Is there another library available to windows to get this information? Thanks for the help. Have a good day.

1 Answers1

1

Do not confuse the GATT Service UUID list returned by bleak with the iBeacon ProximityUUID you want. They are two totally different identifiers. The iBeacon ProximityUUID is encoded inside the manufacturer data returned by bleak. It will not parse it for you, but you could write a parser yourself. If you print out the manufacturer data bytes as hex you will see the pattern.

I wrote a Windows Beacon Library that does what you want. It is a port of the Android Beacon Library for Windows 10. But the documentation is sorely lacking. If you are stuck, I can help you use it, but it is designed to be used with Visual Studio languages not Python.

Using that library you can parse an iBeacon frame from BluetoothLEAdvertisementReceivedEventArgs in C# like this:

var beaconParser = new BeaconParser();
beaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
Beacon beacon = beaconParser.FromAdvertisement(args.Advertisement, args.RawSignalStrengthInDBm, args.BluetoothAddress);
if (beacon != null)
{
    OLogger.Debug("Found iBeacon: UUID=" + beacon.Id1 + " major=" + beacon.Id2 + " minor=" + beacon.Id3 + " rssi: " + beacon.Rssi);
}
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • in this data **\x02\x15\x11\x11\x11\x11""33DDUUUUUU\x02\x00\x01\x00\x01** I got the following **0215111111112222333344445555555555550200010001** and I can identefy what I want, but can you help me understand a little how to know the corretct major and minor? In this example the major is: 0200 and the minor is 0100 and that represent, 512 and 256. But in my server I selected to the major 2 and the minor 1. Do you know why I get that values? Do I realy have 65535 diferent values for? If now how many? Thanks. –  Dec 04 '19 at 22:59
  • 1
    Yes, the major and minor are each two byte fields (values from 0-65535) that immediately follow the ProximityUUID. The reason you are getting 0100 and 0200 instead of 0001 and 0002 probably has to do with "endianness". The byte order is just wrong on your transmitter. It should be "big endian" or most significant byte (MSB) first. – davidgyoung Dec 05 '19 at 00:50
  • oh, ye you right, many thanks for your help, realy. just one last question if you dont mind. In this data **0215111111112222333344445555555555550200010001** do you have any idea what represent the first values? the _02_ and _15_ I know that after is the uuid. manor, minor and another one. –  Dec 05 '19 at 21:44
  • 1
    See the full breakdown of the bytes in my answer [here](https://stackoverflow.com/a/19040616/1461050) – davidgyoung Dec 06 '19 at 02:01
  • The bytes structer doen't match, that's why I'm haing trouble to understand. after the 02 and 15 I have the proximity uuid and in that aswer you have much more before the proximyte uuid. Maybe its the data type and the data lenght? As it is in the below aswer of that link. (minus the company identifier for some reason) –  Dec 06 '19 at 18:40
  • And just one thing, in the secound image that I have in my aswer, in the manufactory_data key value I have a number as a key (76) and then the information, do you have any idea what that means? I think is something with the manufactores I saw that in this link [link](https://bleak.readthedocs.io/en/latest/_modules/bleak/backends/device.html#BLEDevice]) in the str function –  Dec 06 '19 at 20:48
  • That is Apple's manufacturer ID shown as a decimal number. As hex it is 0x4C. Note that same value is in the link above about the iBeacon layout. It is sometimes represented as a key in outputs to indicate the following manufacturer data bytes are for that specific manufacturer ID. But the fact that the library you are using has it as a key is simply an implementation choice of that library. – davidgyoung Dec 08 '19 at 22:44