Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detected Beacon not showing every Frame contained #26

Open
benzben opened this issue Jun 4, 2018 · 1 comment
Open

Detected Beacon not showing every Frame contained #26

benzben opened this issue Jun 4, 2018 · 1 comment

Comments

@benzben
Copy link

benzben commented Jun 4, 2018

I'm trying to implement the UniversalBeacon Library in a HoloLens App.

I am able to detect Beacons, but it's only showing me 1 of the frames my Beacons contains.

My Code looks like that:

    private void BeaconManagerOnBeaconAdded(object sender, Beacon beacon)
    {
        var beaconBuffer = String.Empty;            

        foreach (var beaconFrame in beacon.BeaconFrames.ToList()) //This BeaconManager only shows Eddystone or iBeacon Frames for better visibility
        {
            if (beaconFrame is UidEddystoneFrame)
            {
                beaconBuffer = String.Format("\nBeacon: {0}\nType: {1}\nLast Update: {2}\nRSSI: {3}", beacon.BluetoothAddressAsString, beacon.BeaconType, beacon.Timestamp, beacon.Rssi);
                beaconBuffer = String.Format(beaconBuffer + "\nEddystone UID Frame\nID: {0}", ((UidEddystoneFrame)beaconFrame).NamespaceIdAsNumber.ToString("X") + " / " + 
                    ((UidEddystoneFrame)beaconFrame).InstanceIdAsNumber.ToString("X"));
            }
            else if (beaconFrame is ProximityBeaconFrame)
            {
                beaconBuffer = String.Format("\nBeacon: {0}\nType: {1}\nLast Update: {2}\nRSSI: {3}", beacon.BluetoothAddressAsString, beacon.BeaconType, beacon.Timestamp, beacon.Rssi);
                beaconBuffer = String.Format(beaconBuffer + "\nProximity Beacon Frame (iBeacon compatible)\nUuid: {0}\nMajor: {1}\nMinor: {2}", ((ProximityBeaconFrame)beaconFrame).UuidAsString, 
                    ((ProximityBeaconFrame)beaconFrame).MajorAsString, ((ProximityBeaconFrame)beaconFrame).MinorAsString);
            }
            DetectedAdvertisements.Add(beaconBuffer);
        }

        Debug.WriteLine("\nBeacon: " + beacon.BluetoothAddressAsString);
        Debug.WriteLine("Type: " + beacon.BeaconType);
        Debug.WriteLine("Last Update: " + beacon.Timestamp);
        Debug.WriteLine("RSSI: " + beacon.Rssi);
        foreach (var beaconFrame in beacon.BeaconFrames.ToList())
        {
            // Print a small sample of the available data parsed by the library
            if (beaconFrame is UidEddystoneFrame)
            {
                Debug.WriteLine("Eddystone UID Frame");
                Debug.WriteLine("ID: " + ((UidEddystoneFrame)beaconFrame).NamespaceIdAsNumber.ToString("X") + " / " +
                                ((UidEddystoneFrame)beaconFrame).InstanceIdAsNumber.ToString("X"));
            }
        }
      }

DetectedAdvertisements is a string-List where I can theoretically store the frames contained by one beacon, but it just won't work, I don't know why.
The Debug.WriteLine commands are just to make sure it's actually missing data.

And also, is there a way to scan for changes permanently? My Watcher will only show me the very first succesfull scan of my Beacon and not update anything such as RSSI or time etc.
I read something about using a BeaconManager.BluetoothBeacon.CollectionChanged event for getting continuous updates, how does this work?
I think that this would also solve the problem of not scanning every existing frame of the detected beacon.

I'm using an iBKS Beacon which contains two Eddystone Frames, which I can fully detect using the sample UWP App for the HoloLens, therefore it can't be the hardware.

I hope somebody can help me :-)

@Jones-Abramoff
Copy link

Jones-Abramoff commented Oct 22, 2023

There is a problem with the UpdateBeacon function inside Beacon.cs.
If the app receives an iBeacon advertisement, it will ignore EddyStone data because it will check the BeaconType will not be Unknown, and will never be changed to Eddystone, so it will not be parsed.
I believe that the BeaconType concept is not good in this case, because the same beacon may sent iBeacon and also EddyStone
data, and created a workaround using the variable hasEddystone as below:

            bool hasEddystone = false;

            // Service UUID identifies Eddystone beacon - iBeacon is identified via manufacturer ID
            if (btAdv.Advertisement.ServiceUuids.Any())
            {
                foreach (var serviceUuid in btAdv.Advertisement.ServiceUuids)
                {
                    // If we have multiple service UUIDs and already recognized a beacon type, 
                    // don't overwrite it with another service Uuid.
                    if (BeaconType == BeaconTypeEnum.Unknown)
                    {
                        BeaconType = serviceUuid.Equals(_eddystoneGuid)
                            ? BeaconTypeEnum.Eddystone
                            : BeaconTypeEnum.Unknown;
                    }
                    if (serviceUuid.Equals(_eddystoneGuid))
                    {
                        hasEddystone = true;
                    }
                }
            }
            else
            {
                //Debug.WriteLine("Bluetooth LE device does not send Service UUIDs");
            }

            // Data sections - used by Eddystone Beacon type
            if (btAdv.Advertisement.DataSections.Any())
            {
                if (hasEddystone)
                {
                    // This beacon is according to the Eddystone specification - parse data
                    ParseEddystoneData(btAdv);
                }

It's not a fix, just a workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants