コード例 #1
0
        private void ParseEddystoneData(BluetoothLEAdvertisementReceivedEventArgs btAdv)
        {
            // Parse Eddystone data
            foreach (var dataSection in btAdv.Advertisement.DataSections)
            {
                //Debug.WriteLine("Beacon data: " + dataSection.DataType + " = " +
                //                BitConverter.ToString(dataSection.Data.ToArray()));
                //+ " (" + Encoding.UTF8.GetString(dataSection.Data.ToArray()) + ")\n");

                // Relvant data of Eddystone is in data section 0x16
                // Windows receives: 0x01 = 0x06
                //                   0x03 = 0xAA 0xFE
                //                   0x16 = 0xAA 0xFE [type] [data]
                if (dataSection.DataType == 0x16)
                {
                    var beaconFrame = dataSection.Data.ToArray().CreateEddystoneBeaconFrame();
                    if (beaconFrame == null)
                    {
                        continue;
                    }

                    var found = false;

                    for (var i = 0; i < BeaconFrames.Count; i++)
                    {
                        if (BeaconFrames[i].GetType() == beaconFrame.GetType())
                        {
                            var updateFrame = false;
                            if (beaconFrame.GetType() == typeof(UnknownBeaconFrame))
                            {
                                // Unknown frame - also compare eddystone type
                                var existingEddystoneFrameType =
                                    BeaconFrames[i].Payload.GetEddystoneFrameType();
                                var newEddystoneFrameType = beaconFrame.Payload.GetEddystoneFrameType();
                                if (existingEddystoneFrameType != null &&
                                    existingEddystoneFrameType == newEddystoneFrameType)
                                {
                                    updateFrame = true;
                                }
                            }
                            else
                            {
                                updateFrame = true;
                            }
                            if (updateFrame)
                            {
                                BeaconFrames[i].Update(beaconFrame);
                                found = true;
                                break;  // Don't analyze any other known frames of this beacon
                            }
                        }
                    }

                    if (!found)
                    {
                        BeaconFrames.Add(beaconFrame);
                    }
                }
            }
        }
コード例 #2
0
        private void ParseAxaBeaconData(BluetoothLEAdvertisementReceivedEventArgs btAdv)
        {
            BeaconFrameBase beaconFrame = null;

            if (btAdv.Advertisement.DataSections.Any(_ => _.DataType == 9))
            {
                var data = btAdv.Advertisement.DataSections.First(_ => _.DataType == 9).Data.ToArray();

                beaconFrame = new AxaCompleteNameFrame(data);
            }
            else if (btAdv.Advertisement.DataSections.Any(_ => _.DataType == 22))
            {
                var data = btAdv.Advertisement.DataSections.First(_ => _.DataType == 22).Data.ToArray();

                beaconFrame = new AxaBatTempHumFrame(data);
            }

            if (beaconFrame != null)
            {
                var existingFrame = BeaconFrames.FirstOrDefault(_ => _.GetType() == beaconFrame.GetType());

                if (existingFrame != null)
                {
                    existingFrame.Update(beaconFrame);
                }
                else
                {
                    BeaconFrames.Add(beaconFrame);
                }
            }
        }
コード例 #3
0
ファイル: Beacon.cs プロジェクト: gk-8/Beacon-Insights
        private void UpdateRawPayload()
        {
            string raw = "";

            foreach (var frame in BeaconFrames)
            {
                raw += "[Frame " + (BeaconFrames.IndexOf(frame) + 1) + "] " + BitConverter.ToString(frame.Payload);
                if (BeaconFrames.IndexOf(frame) < BeaconFrames.Count - 1)
                {
                    raw += "\n\n";
                }
            }

            RawPayloadFormattedString = raw;
        }
コード例 #4
0
        /// <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);
                        }
                    }
                }
            }
        }
コード例 #5
0
        /// <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;
            }

            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 == BeaconTypeEnum.Unknown)
                    {
                        BeaconType = serviceUuid.Equals(_eddystoneGuid)
                            ? BeaconTypeEnum.Eddystone
                            : BeaconTypeEnum.Unknown;
                    }
                }
            }
            else
            {
                //Debug.WriteLine("Bluetooth LE device does not send Service UUIDs");
            }

            // Data sections
            if (btAdv.Advertisement.DataSections.Any())
            {
                if (BeaconType == BeaconTypeEnum.Eddystone)
                {
                    // This beacon is according to the Eddystone specification - parse data
                    ParseEddystoneData(btAdv);
                }
            }

            // 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);
                    var manufacturerDataArry = manufacturerData.Data.ToArray();
                    if (manufacturerData.CompanyId == 0x4C && manufacturerData.Data.Length >= 23 &&
                        manufacturerDataArry[0] == 0x02)
                    {
                        BeaconType = BeaconTypeEnum.iBeacon;
                        //Debug.WriteLine("iBeacon Frame: " + BitConverter.ToString(manufacturerDataArry));
                        // Only one relevant data frame for iBeacons
                        if (BeaconFrames.Any())
                        {
                            BeaconFrames[0].Payload = manufacturerDataArry;
                        }
                        else
                        {
                            BeaconFrames.Add(new UnknownBeaconFrame(manufacturerDataArry));
                        }
                    }
                    else if ((manufacturerData.CompanyId & 0x150) == 0x150)
                    {
                        BluetoothAddress = GetEstimoteAddress(btAdv);

                        if (BeaconFrames.Any())
                        {
                            BeaconFrames[0].Payload = manufacturerDataArry;
                            ((EstimoteNearableFrame)BeaconFrames[0]).ParsePayload();
                        }

                        if (manufacturerDataArry[0] == 0x01)
                        {
                            BeaconType = BeaconTypeEnum.EstimoteNearable;

                            EstimoteNearableFrame enf = new EstimoteNearableFrame(manufacturerDataArry);
                            enf.PropertyChanged += Enf_PropertyChanged;
                            if (!BeaconFrames.Any())
                            {
                                BeaconFrames.Add(enf);
                            }
                        }
                        else
                        {
                            BeaconType = BeaconTypeEnum.EstimoteStone;
                        }
                    }
                }
            }

            if (_bluetoothAddress == null)
            {
                BluetoothAddress = BitConverter.GetBytes(btAdv.BluetoothAddress);
            }

            //if (!CheckAddress(btAdv))
            //{
            //    throw new BeaconException("Bluetooth address of beacon does not match - not updating beacon information");
            //}
        }