0

MS provided samples to send and receive Bluetooth Low Energy advertisements. I saw this very helpful answer for breaking down the iBeacon packet. There's also an example for setting BluetoothLEAdvertisement.ManufacturerData as the ibeacon standards.

May I ask how can I set the Flags of the BluetoothLEAdvertisement? For example set the value to: 02-01-06

Thanks


Edit 1: Here's the code:

using System;
using System.Management;
using System.Text.RegularExpressions;
using Windows.Devices.Bluetooth.Advertisement;
using System.Runtime.InteropServices.WindowsRuntime;

namespace BLE_iBeacon
{
    class IBeacon
    {
        static void Main()
        {
            Console.WriteLine("Advertising as iBeacon. Press Enter to exit");

            // Create and initialize a new publisher instance.
            BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();

            // Add a manufacturer-specific section:
            var manufacturerData = new BluetoothLEManufacturerData();

            // Set the company ID for the manufacturer data.
            // 0x004C   Apple, Inc.
            manufacturerData.CompanyId = 0x004C;

            byte[] dataArray = new byte[] {
                // last 2 bytes of Apple's iBeacon
                0x02, 0x15,
                // UUID E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7
                0xE4, 0xC8, 0xA4, 0xFC,
                0xF6, 0x8B, 0x47, 0x0D,
                0x95, 0x9F, 0x29, 0x38,
                0x2A, 0xF7, 0x2C, 0xE7,
                // Major
                0x00, 0x00,
                // Minor
                0x00, 0x01,
                // TX power
                0xC5
            };

            manufacturerData.Data = dataArray.AsBuffer();

            // Add the manufacturer data to the advertisement publisher:
            publisher.Advertisement.ManufacturerData.Add(manufacturerData);

            publisher.Advertisement.Flags = BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;

            publisher.Start();
            Console.Read();
            publisher.Stop();
        }
    }
}

Edit 2:

In the C# code if I do not set the Flags, my windows laptop would advertise raw packet like:

04 3E 27 02 01 
02 01 0D 45 84 D3 68 21 1B 1A FF 4C 00 
02 15 E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7 
00 00 00 01 C5 BA

My purpose is to use raspberry pi's as BLE receivers. I used the Radius Networks's code here. You can see in the ibeacon_scan script, they check the packet of the advertisement to see if it's an iBeacon by:

if [[ $packet =~ ^04\ 3E\ 2A\ 02\ 01\ .{26}\ 02\ 01\ .{14}\ 02\ 15 ]]; then

So the previous raw packet would not be recognized, for missing the flag part. I am wondering if I can advertise the packet with the Flags, like:

04 3E 2A 02 01 
02 01 0D 45 84 D3 68 21 1B **02 01 1A** 1A FF 4C 00 
02 15 E4 C8 A4 FC F6 8B 47 0D 95 9F 29 38 2A F7 2C E7 
00 00 00 01 C5 BA

instead of changing the scan script in the pi.

Community
  • 1
  • 1
Rushhour Park
  • 11
  • 1
  • 6

2 Answers2

2

iBeacon on Windows

The following code publishes an iBeacon on Windows 10 machines:

// Create and initialize a new publisher instance.
BluetoothLEAdvertisementPublisher publisher = new BluetoothLEAdvertisementPublisher();

// Add a manufacturer-specific section:
var manufacturerData = new BluetoothLEManufacturerData();

// Set the company ID for the manufacturer data.
// 0x004C   Apple, Inc.
manufacturerData.CompanyId = 0x004c;

// Create the payload
var writer = new DataWriter();
byte[] dataArray = new byte[] {
    // last 2 bytes of Apple's iBeacon
    0x02, 0x15,
    // UUID e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0
    0xe2, 0xc5, 0x6d, 0xb5, 
    0xdf, 0xfb, 0x48, 0xd2, 
    0xb0, 0x60, 0xd0, 0xf5, 
    0xa7, 0x10, 0x96, 0xe0,
    // Major
    0x00, 0x00,
    // Minor
    0x00, 0x01,
    // TX power
    0xc5
};
writer.WriteBytes(dataArray);

manufacturerData.Data = writer.DetachBuffer();

// Add the manufacturer data to the advertisement publisher:
publisher.Advertisement.ManufacturerData.Add(manufacturerData);

publisher.Start();

Proximity UUID

While testing this out, my iOS device would not recognize the Proximity UUID you provided. I'm guessing this is because you generated it yourself, so the app doesn't know what to look for. Instead, I used the proximity UUID from this answer which identifies the Windows 10 device as an AirLocate iBeacon.

Flags

Windows 10 does not currently allow developers to set the flags for a Bluetooth LE advertisement. Luckily, for the Windows device to be recognized as an iBeacon, you don't need those flags!

Community
  • 1
  • 1
Carter
  • 3,053
  • 1
  • 17
  • 22
  • Thank you very much! I added: *publisher.Advertisement.Flags = BluetoothLEAdvertisementFlags.GeneralDiscoverableMode;* in between: *publisher.Advertisement.ManufacturerData.Add(manufacturerData);* and *publisher.Start();* But I get the following error: *An unhandled exception of type 'System.Exception' occurred ... Additional information: The data is invalid. Invalid advertisement payload detected.* – Rushhour Park Jun 15 '16 at 16:13
  • Could you add the advertisement creation code to the question (or a gist) so we can see what's going on? – Carter Jun 15 '16 at 16:16
  • Original question edited with the creation code added. Thanks! – Rushhour Park Jun 15 '16 at 17:05
  • I have this working on my end, I'll update my answer :) – Carter Jun 15 '16 at 18:04
  • Thanks a lot! [This answer](http://stackoverflow.com/a/30099911/6451649) gives the code for reading the uuid of the motherboard. But that's the next step. Currently I just need to let the proximity uuid to be read. I just updated my question but it looks that I have to change the scan script in the pi ... – Rushhour Park Jun 15 '16 at 20:22
  • Yes, it's not currently possible to change the flags on the Windows side, so you have to change the scan script in the pi. Just removing the flag checking part on the pi would be enough. – Carter Jun 15 '16 at 20:48
1

Ideally, you want to set the flags byte to 0x1a, but other values may still work. The important flag to set is General Discoverable (0x02).

You can use BluetoothLEAdvertisementFlags is an enumeration of bit values here.

My C# is very rusty, but you might try setting the flags hex value directly with: publisher.Advertisement.Flags = 0x1A;

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • Thanks for the remind! But I still get the following error: "an explicit conversion exists" – Rushhour Park Jun 13 '16 at 13:29
  • Sorry, I'm not surprised by that error. Perhaps somebody with less rusty C# skills (or a working C# dev environment) can figure out the right syntax to set that flag value based on what I have posted. – davidgyoung Jun 13 '16 at 15:42