/// <summary> /// Update the raw payload when properties have changed. /// </summary> private void UpdatePayload() { if (NamespaceId == null || NamespaceId.Length != 10 || InstanceId == null || InstanceId.Length != 6) { _payload = null; return; } var header = BeaconFrameHelper.CreateEddystoneHeader(BeaconFrameHelper.EddystoneFrameType.UidFrameType); using (var ms = new MemoryStream()) { // Frame header ms.Write(header, 0, header.Length); // Ranging data ms.WriteByte((byte)RangingData); // Namespace ID ms.Write(NamespaceId, 0, NamespaceId.Length); // Instance ID ms.Write(InstanceId, 0, InstanceId.Length); // RFU (2 bytes, must be 0x00) ms.WriteByte(0x00); ms.WriteByte(0x00); // Save to payload (to direct array to prevent re-parsing and a potential endless loop of updating and parsing) _payload = ms.ToArray(); } }
/// <summary> /// Update the raw payload when properties have changed. /// </summary> private void UpdatePayload() { if (string.IsNullOrEmpty(CompleteUrl)) { _payload = null; return; } var urlSchemeByte = EncodeUrlScheme(CompleteUrl); // Check if the URL starts with a valid header (only the defined ones are allowed) if (urlSchemeByte == null) { _payload = null; return; } var header = BeaconFrameHelper.CreateEddystoneHeader(BeaconFrameHelper.EddystoneFrameType.UrlFrameType); using (var ms = new MemoryStream()) { // Frame header ms.Write(header, 0, header.Length); // Ranging data ms.WriteByte((byte)RangingData); // URL scheme byte ms.WriteByte((byte)urlSchemeByte); // Encoded URL EncodeUrlToStream(CompleteUrl, UrlSchemeDictionary[(byte)urlSchemeByte].Length, ms); // Save to payload (to direct array to prevent re-parsing and a potential endless loop of updating and parsing) _payload = ms.ToArray(); } }
/// <summary> /// Update the raw payload when properties have changed. /// </summary> private void UpdatePayload() { var header = BeaconFrameHelper.CreateEddystoneHeader(BeaconFrameHelper.EddystoneFrameType.TelemetryFrameType); using (var ms = new MemoryStream()) { // Frame header ms.Write(header, 0, header.Length); // Version ms.WriteByte(Version); // Battery var batBytes = BitConverter.GetBytes(BatteryInMilliV); if (BitConverter.IsLittleEndian) { Array.Reverse(batBytes); } ms.Write(batBytes, 0, batBytes.Length); // Temperature // #define float2fix(a) ((int)((a)*256.0)) //Convert float to fix. a is a float var temp = ((int)((TemperatureInC) * 256.0)); var tempBytes = BitConverter.GetBytes(temp); if (BitConverter.IsLittleEndian) { Array.Reverse(tempBytes); } ms.Write(tempBytes, 2, 2); // ADV_CNT var advCntBytes = BitConverter.GetBytes(AdvertisementFrameCount); if (BitConverter.IsLittleEndian) { Array.Reverse(advCntBytes); } ms.Write(advCntBytes, 0, 4); // SEC_CNT var secCntBytes = BitConverter.GetBytes(TimeSincePowerUp); if (BitConverter.IsLittleEndian) { Array.Reverse(secCntBytes); } ms.Write(secCntBytes, 0, 4); // Save to payload (to direct array to prevent re-parsing and a potential endless loop of updating and parsing) _payload = ms.ToArray(); } }
/// <summary> /// Received a new advertisement for this beacon. /// If the Bluetooth address of the new advertisement matches this beacon, /// it will parse the contents of the advertisement and extract known frames. /// </summary> /// <param name="btAdv">Bluetooth advertisement to parse, as received from /// the Windows Bluetooth LE API.</param> public void UpdateBeacon(BluetoothLEAdvertisementReceivedEventArgs btAdv) { if (btAdv == null) { return; } if (btAdv.BluetoothAddress != BluetoothAddress) { throw new BeaconException("Bluetooth address of beacon does not match - not updating beacon information"); } Rssi = btAdv.RawSignalStrengthInDBm; Timestamp = btAdv.Timestamp; //Debug.WriteLine($"Beacon advertisment detected (Strength: {Rssi}): Address: {BluetoothAddress}"); // Check if beacon advertisement contains any actual usable data if (btAdv.Advertisement == null) { return; } 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 == BeaconType.Unknown) { BeaconType = serviceUuid.ToBeaconType(); } } } else { //Debug.WriteLine("Bluetooth LE device does not send Service UUIDs"); } // Data sections if (btAdv.Advertisement.DataSections.Any()) { if (BeaconType == BeaconType.Eddystone) { ParseEddystoneData(btAdv); } else if (BeaconType == BeaconType.AXABeacon) { ParseAxaBeaconData(btAdv); } else if (BeaconType == BeaconType.Unknown) { // Unknown beacon type //Debug.WriteLine("\nUnknown beacon"); //foreach (var dataSection in btAdv.Advertisement.DataSections) //{ // Debug.WriteLine("Data section 0x: " + dataSection.DataType.ToString("X") + " = " + // BitConverter.ToString(dataSection.Data.ToArray())); //} } } // Manufacturer data - currently unused if (btAdv.Advertisement.ManufacturerData.Any()) { foreach (var manufacturerData in btAdv.Advertisement.ManufacturerData) { // Print the company ID + the raw data in hex format //var manufacturerDataString = $"0x{manufacturerData.CompanyId.ToString("X")}: {BitConverter.ToString(manufacturerData.Data.ToArray())}"; //Debug.WriteLine("Manufacturer data: " + manufacturerDataString); ManufacturerId = manufacturerData.CompanyId; var manufacturerDataArry = manufacturerData.Data.ToArray(); if (BeaconFrameHelper.IsProximityBeaconPayload(manufacturerData.CompanyId, manufacturerDataArry)) { //BeaconType = BeaconType.iBeacon; //Debug.WriteLine("iBeacon Frame: " + BitConverter.ToString(manufacturerDataArry)); var beaconFrame = new ProximityBeaconFrame(manufacturerDataArry); // Only one relevant data frame for iBeacons if (BeaconFrames.Any()) { BeaconFrames[0].Update(beaconFrame); } else { BeaconFrames.Add(beaconFrame); } } } } }