Bluetooth LE, 'Low Energy', also 'Bluetooth Smart', is a core technology for the IoT, Internet of Things: It is the way how little 'intelligent' 'Things' ('peripherals') can do their 'thing' and communicate it to the rest of the world.
To announce themselves, they can publish little messages called 'Advertisements'. A sensor might sit in the roof and call out every 100 milliseconds "I'm here. I'm here. I'm here. You can get the temperature from me. I'm here. I'm here. You can get the temperature from me.", and because it is 'low energy', it can do that for a long time.
What if we want to publish BLE advertisements using Windows?
It is possible to publish Bluetooth LE advertisements with the class Windows.Devices.Bluetooth.Advertisement.BluetoothLEAdvertisementPublisher. Sample code from Microsoft is here.
This is how the sample code does it:
publisher = new BluetoothLEAdvertisementPublisher();
...
var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 0xFFFE;
var writer = new DataWriter();
UInt16 uuidData = 0x1234;
writer.WriteUInt16(uuidData);
manufacturerData.Data = writer.DetachBuffer();
publisher.Advertisement.ManufacturerData.Add(manufacturerData);
...
publisher.StatusChanged += OnPublisherStatusChanged;
publisher.Start();
This will only work if the app requests 'Bluetooth' capabilities in its appManifest:
In Visual Studio:
Package.appmanifest -> Capabilities -> Ensure 'Bluetooth' is checked.
In a text editor:
Open Package.appmanifest in a text or xml editor:
<Capabilities>
...
<DeviceCapability Name="bluetooth" />
...
</Capabilities>
Notes here:
- Without manufacturer data, the publisher won't get started. Start() will throw a COMException with the message :
"The data is invalid. Publisher can only be started with a non-empty payload." - The StatusChanged event comes back with a status and an error, which are both enums.
Status can be:
Success, RadioNotAvailable, ResourceInUse, DeviceNotConnected, OtherError, DisabledByPolicy, NotSupported, DisabledByUser.
Error can be:
Created, Waiting, Started, Stopping, Stopped, Aborted.
E.g., after Start()ing a publisher without a Bluetooth LE device installed in the computer, the status was 'RadioNotAvailable'.
When the App had not requested the 'Bluetooth' capability in the Package.appmanifest file, the status was 'OtherError'.
After fixing these errors, it all worked, and other BLE devices could see my advertised publisher. However, these other devices see my publisher as 'Unnamed', 'no name', or 'unknown'. My publisher does not advertise a name. This is where the sample ends, it does not show how to publish a name.
A 'Local Name' is normally advertised in the DataSections of the advertisement, so we could try to add a DataSection:
var dataSection = new BluetoothLEAdvertisementDataSection();
byte dataType = BluetoothLEAdvertisementDataTypes.CompleteLocalName;
dataSection.DataType = (byte)dataType;
writer = new DataWriter();
writer.WriteString("MyName");
dataSection.Data = writer.DetachBuffer();
However, if doing so, then publisher.Start() also throws a COMException:
"The data is invalid.\r\n\r\nInvalid advertisement payload detected."
Which is not surprising because this is documented for the BluetoothAdvertisementPublisher class.
According to this, nearly all interesting advertisement datasection types are "system-reserved and are not allowed".
This includes the Shortened Local Name (Data type 0x08), Complete Local Name (Data type 0x09), Class Of Device (Data type 0x0D), and all complete and incomplete lists of service UUIds (Data types 0x02-0x07).
So, no way for us to say "I'm here. I'm here. I'm here. You can get a Http Proxy from me."
No way to advertise a name when I publish a BluetoothLEAdvertisement. No way to publish a service or a characteristic.
Moreover, there is nothing here in the API to tell me if someone who sees my published advertisements wants to connect or pair with me.
But there are more people wanting this, so, watch this space.