We are trying to read the data of a EddyStone beacon, so we can do something with the URL. However, when formatting we keep getting ???goo.gl/..
We wrote some code to log the data in the received bluetooth data.
private void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
// We only need the scannable devices containing data
if (eventArgs.AdvertisementType != BluetoothLEAdvertisementType.ConnectableUndirected || eventArgs.Advertisement.DataSections.Count < 3)
return;
// Do whatever you want with the advertisement
Encoding asciiEncoding = ASCIIEncoding.ASCII;
System.Diagnostics.Debug.WriteLine("=========================================================================================== NEW ADVERTISEMENT ===========================================================================================");
System.Diagnostics.Debug.WriteLine("Address: " + eventArgs.BluetoothAddress);
System.Diagnostics.Debug.WriteLine("Type: " + eventArgs.AdvertisementType);
System.Diagnostics.Debug.WriteLine("Strength: " + eventArgs.RawSignalStrengthInDBm);
System.Diagnostics.Debug.WriteLine("Datasections Count: " + eventArgs.Advertisement.DataSections.Count);
System.Diagnostics.Debug.WriteLine("Flags: " + eventArgs.Advertisement.Flags);
System.Diagnostics.Debug.WriteLine("LocalName: " + eventArgs.Advertisement.LocalName);
System.Diagnostics.Debug.WriteLine("Uuids: " + eventArgs.Advertisement.ServiceUuids[0]);
string output = "";
int i = 1;
foreach(BluetoothLEAdvertisementDataSection data in eventArgs.Advertisement.DataSections)
{
var dataReader = Windows.Storage.Streams.DataReader.FromBuffer(data.Data);
System.Diagnostics.Debug.WriteLine("Data Length: " + data.Data.Length + " / DataReader: " + dataReader.UnconsumedBufferLength);
byte[] fileContent = new byte[dataReader.UnconsumedBufferLength];
dataReader.ReadBytes(fileContent);
string hexString = BitConverter.ToString(fileContent);
System.Diagnostics.Debug.WriteLine("Datasection" + i + ": " + BitConverter.ToString(fileContent));
string dataSectionOutput = asciiEncoding.GetString(fileContent, 0, fileContent.Length);
System.Diagnostics.Debug.WriteLine("Datasection" + i + ": " + dataSectionOutput);
output += dataSectionOutput;
output = output.Replace("?", "");
i++;
}
System.Diagnostics.Debug.WriteLine("Output: " + output.ToString());
}
This is our output
Address: 220868346281848
Type: ConnectableUndirected
Strength: -75
Datasections Count: 3
Flags: GeneralDiscoverableMode, ClassicNotSupported
LocalName:
Uuids: 0000feaa-0000-1000-8000-00805f9b34fb
Data Length: 1 / DataReader: 1
Datasection1: 06
Datasection1:
Data Length: 2 / DataReader: 2
Datasection2: AA-FE
Datasection2: ??
Data Length: 18 / DataReader: 18
Datasection3: AA-FE-10-EB-03-67-6F-6F-2E-67-6C-2F-79-54-35-56-61-64
Datasection3: ???goo.gl/yT5Vad
Output: goo.gl/yT5Vad
What encoding/decoding do we have to use?
According to the EddyStone spec an EddyStone frame starts with the bytes AA-FE
. A single byte specifying the frame type follows after that. 0x10
is the identifier for a url frame.
After that, a single byte representing the transmission power is included, which you can probably ignore.
Then, a single byte representing scheme follows, with the url after that. The url is encoded using the printable part of ASCII, the unprintable characters are used for compression.
Once you have determined the correct section (that is, starting with AA-FE-10
) parsing should be relatively straightforward.