示例#1
0
        public void TestCanParseLocationBeacon()
        {
            double latitude  = 38.93;
            double longitude = -77.23;
            var    beacon    = new Beacon.Builder()
                               .SetManufacturer(0x0118) // Radius Networks
                               .SetId1("1")             // device sequence number
                               .SetId2(String.Format("{0:X8}", (long)((latitude + 90) * 10000.0)))
                               .SetId3(String.Format("{0:X8}", (long)((longitude + 180) * 10000.0)))
                               .SetTxPower(-59) // The measured transmitter power at one meter in dBm
                               .Build();
            // TODO: make this pass if data fields are little endian or > 4 bytes (or even > 2 bytes)
            var p = new BeaconParser().
                    SetBeaconLayout("m:2-3=10ca,i:4-9,i:10-13,i:14-17,p:18-18");
            var bytes       = p.GetBeaconAdvertisementData(beacon);
            var headerBytes = HexStringToByteArray("02011a1bff1801");
            var advBytes    = new byte[bytes.Length + headerBytes.Length];

            Array.Copy(headerBytes, 0, advBytes, 0, headerBytes.Length);
            Array.Copy(bytes, 0, advBytes, headerBytes.Length, bytes.Length);

            Beacon parsedBeacon = p.FromScanData(advBytes, -59, null);

            AssertEx.NotNull(String.Format("Parsed beacon from {0} should not be null", ByteArrayToHexString(advBytes)), parsedBeacon);
            double parsedLatitude  = Int64.Parse(parsedBeacon.Id2.ToString().Substring(2), System.Globalization.NumberStyles.HexNumber) / 10000.0 - 90.0;
            double parsedLongitude = Int64.Parse(parsedBeacon.Id3.ToString().Substring(2), System.Globalization.NumberStyles.HexNumber) / 10000.0 - 180.0;

            long encodedLatitude = (long)((latitude + 90) * 10000.0);

            AssertEx.AreEqual("encoded latitude hex should match", string.Format("0x{0:x8}", encodedLatitude).ToLowerInvariant(), parsedBeacon.Id2.ToString().ToLowerInvariant());
            AssertEx.AreEqual("device sequence num should be same", "0x000000000001", parsedBeacon.Id1.ToString());
            AssertEx.AreEqual("latitude should be about right", latitude, parsedLatitude, 0.0001);
            AssertEx.AreEqual("longitude should be about right", longitude, parsedLongitude, 0.0001);
        }
        public void TestDetectsEddystoneUID()
        {
            byte[]       bytes              = HexStringToByteArray("0201060303aafe1516aafe00e700010203040506070809010203040506000000000000000000000000000000000000000000000000000000000000000000");
            BeaconParser parser             = new BeaconParser().SetBeaconLayout(BeaconParser.EddystoneUidLayout);
            Beacon       eddystoneUidBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("Eddystone-UID should be not null if parsed successfully", eddystoneUidBeacon);
        }
示例#3
0
        public void TestAllowsAccessToParserIdentifier()
        {
            var bytes  = HexStringToByteArray("02011a1aff180112342f234454cf6d4a0fadf2f4911ba9ffa600010002c5");
            var parser = new BeaconParser("my_beacon_type");

            parser.SetBeaconLayout("m:2-3=1234,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("parser identifier should be accessible", "my_beacon_type", beacon.ParserIdentifier);
        }
示例#4
0
        public void TestLongUrlBeaconIdentifier()
        {
            var bytes  = HexStringToByteArray("0201060303aafe0d16aafe10e70102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f00000000000000000000000000000000000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("URL Identifier should be truncated at 8 bytes", 8, beacon.Id1.ToByteArray().Length);
        }
示例#5
0
        public void TestRecognizeBeaconCapturedManufacturer()
        {
            var bytes  = HexStringToByteArray("0201061bffaabbbeace2c56db5dffb48d2b060d0f5a71096e000010004c50000000000000000000000000000000000000000000000000000000000000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("manufacturer should be parsed", "bbaa", beacon.Manufacturer.ToString("X").ToLowerInvariant());
        }
        public void TestDetectsGattBeacon2MaxLength()
        {
            byte[]       bytes      = HexStringToByteArray("020106030334121616341210ec007261646975736e6574776f726b7373070000000000000000000000000000000000000000000000000000000000000000");
            BeaconParser parser     = new BeaconParser().SetBeaconLayout("s:0-1=1234,m:2-2=10,p:3-3:-41,i:4-20v");
            Beacon       gattBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("GattBeacon should be not null if parsed successfully", gattBeacon);
            AssertEx.AreEqual("GattBeacon identifier length should be proper length",
                              17,
                              gattBeacon.Id1.ToByteArray().Length);
        }
示例#7
0
        public void TestParseGattIdentifierThatRunsOverPduLength()
        {
            var bytes  = HexStringToByteArray("0201060303aafe0d16aafe10e702676f6f676c65000c09526164426561636f6e204700000000000000000000000000000000000000000000000000000000");
            var parser = new BeaconParser();

            parser.SetAllowPduOverflow(Java.Lang.Boolean.False);
            parser.SetBeaconLayout("s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.Null("beacon should not be parsed", beacon);
        }
示例#8
0
        public void TestReEncodesLittleEndianBeacon()
        {
            var bytes  = HexStringToByteArray("02011a1bff1801beac0102030405060708090a0b0c0d0e0f1011121314c509");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-9,i:10-15l,i:16-23,p:24-24,d:25-25");
            var beacon           = parser.FromScanData(bytes, -55, null);
            var regeneratedBytes = parser.GetBeaconAdvertisementData(beacon);
            var expectedMatch    = Java.Util.Arrays.CopyOfRange(bytes, 7, bytes.Length);

            AssertEx.AreEqual("beacon advertisement bytes should be the same after re-encoding", ByteArrayToHexString(expectedMatch), ByteArrayToHexString(regeneratedBytes));
        }
示例#9
0
        public void TestReEncodesBeaconForEddystoneTelemetry()
        {
            var bytes  = HexStringToByteArray("0201060303aafe1516aafe2001021203130414243405152535");
            var parser = new BeaconParser();

            parser.SetBeaconLayout(BeaconParser.EddystoneTlmLayout);
            var beacon           = parser.FromScanData(bytes, -55, null);
            var regeneratedBytes = parser.GetBeaconAdvertisementData(beacon);
            var expectedMatch    = Java.Util.Arrays.CopyOfRange(bytes, 11, bytes.Length);

            AssertEx.AreEqual("beacon advertisement bytes should be the same after re-encoding", ByteArrayToHexString(expectedMatch), ByteArrayToHexString(regeneratedBytes));
        }
        public void TestDetectsGattBeaconWithCnn()
        {
            byte[]       bytes  = HexStringToByteArray("020106030334120a16341210ed00636e6e070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
            BeaconParser parser = new BeaconParser().SetBeaconLayout("s:0-1=1234,m:2-2=10,p:3-3:-41,i:4-20v");

            Beacon gattBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("GattBeacon should be not null if parsed successfully", gattBeacon);
            AssertEx.AreEqual("GattBeacon identifier length should be adjusted smaller if packet is short",
                              5,
                              gattBeacon.Id1.ToByteArray().Length);
        }
示例#11
0
        public void TestReEncodesBeacon()
        {
            var bytes  = HexStringToByteArray("02011a1bff1801beac2f234454cf6d4a0fadf2f4911ba9ffa600010002c509");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
            var beacon           = parser.FromScanData(bytes, -55, null);
            var regeneratedBytes = parser.GetBeaconAdvertisementData(beacon);
            var expectedMatch    = Java.Util.Arrays.CopyOfRange(bytes, 7, bytes.Length);

            AssertEx.AreEqual("beacon advertisement bytes should be the same after re-encoding", expectedMatch, regeneratedBytes);
        }
        public void TestDetectsGattBeacon()
        {
            byte[]       bytes  = HexStringToByteArray("020106030334121516341200e72f234454f4911ba9ffa6000000000001000000000000000000000000000000000000000000000000000000000000000000");
            BeaconParser parser = new BeaconParser().SetBeaconLayout("s:0-1=1234,m:2-2=00,p:3-3:-41,i:4-13,i:14-19");

            AssertEx.NotNull("Service uuid parsed should not be null", parser.ServiceUuid);
            Beacon gattBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("GattBeacon should be not null if parsed successfully", gattBeacon);
            AssertEx.AreEqual("id1 should be parsed", "0x2f234454f4911ba9ffa6", gattBeacon.Id1.ToString());
            AssertEx.AreEqual("id2 should be parsed", "0x000000000001", gattBeacon.Id2.ToString());
            AssertEx.AreEqual("serviceUuid should be parsed", 0x1234, gattBeacon.ServiceUuid);
            AssertEx.AreEqual("txPower should be parsed", -66, gattBeacon.TxPower);
        }
示例#13
0
        public void TestParseManufacturerIdentifierThatRunsOverPduLength()
        {
            // Note that the length field below is 0x16 instead of 0x1b, indicating that the packet ends
            // one byte before the second identifier field starts
            var bytes  = HexStringToByteArray("02011a16ff1801beac2f234454cf6d4a0fadf2f4911ba9ffa600010002c509000000");
            var parser = new BeaconParser();

            parser.SetAllowPduOverflow(Java.Lang.Boolean.False);
            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");

            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.Null("beacon should not be parsed", beacon);
        }
示例#14
0
        public void TestParseProblematicBeaconFromIssue229()
        {
            // Note that the length field below is 0x16 instead of 0x1b, indicating that the packet ends
            // one byte before the second identifier field starts

            var bytes  = HexStringToByteArray("0201061bffe000beac7777772e626c756b692e636f6d000100010001abaa000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");

            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.NotNull("beacon should be parsed", beacon);
        }
示例#15
0
        public void TestLittleEndianIdentifierParsing()
        {
            var bytes  = HexStringToByteArray("02011a1bff1801beac0102030405060708090a0b0c0d0e0f1011121314c50900000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-9,i:10-15l,i:16-23,p:24-24,d:25-25");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("mRssi should be as passed in", -55, beacon.Rssi);
            AssertEx.AreEqual("id1 should be big endian", "0x010203040506", beacon.GetIdentifier(0).ToString());
            AssertEx.AreEqual("id2 should be little endian", "0x0c0b0a090807", beacon.GetIdentifier(1).ToString());
            AssertEx.AreEqual("id3 should be big endian", "0x0d0e0f1011121314", beacon.GetIdentifier(2).ToString());
            AssertEx.AreEqual("txPower should be parsed", -59, beacon.TxPower);
            AssertEx.AreEqual("manufacturer should be parsed", 0x118, beacon.Manufacturer);
        }
示例#16
0
        public void TestRecognizeBeaconWithFormatSpecifyingManufacturer()
        {
            var bytes  = HexStringToByteArray("02011a1bff1801beac2f234454cf6d4a0fadf2f4911ba9ffa600010002c509000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:0-3=1801beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("mRssi should be as passed in", -55, beacon.Rssi);
            AssertEx.AreEqual("uuid should be parsed", "2f234454-cf6d-4a0f-adf2-f4911ba9ffa6", beacon.GetIdentifier(0).ToString());
            AssertEx.AreEqual("id2 should be parsed", "1", beacon.GetIdentifier(1).ToString());
            AssertEx.AreEqual("id3 should be parsed", "2", beacon.GetIdentifier(2).ToString());
            AssertEx.AreEqual("txPower should be parsed", -59, beacon.TxPower);
            AssertEx.AreEqual("manufacturer should be parsed", 0x118, beacon.Manufacturer);
        }
示例#17
0
        public void DoesNotCashWithOverflowingByteCodeComparisonOnPdu()
        {
            // Test for https://github.com/AltBeacon/android-beacon-library/issues/323

            // Note that the length field below is 0x16 instead of 0x1b, indicating that the packet ends
            // one byte before the second identifier field starts

            var bytes  = HexStringToByteArray("02010604ffe000be");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");

            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.Null("beacon not be parsed without an exception being thrown", beacon);
        }
        public void TestDetectsUriBeacon()
        {
            //"https://goo.gl/hqBXE1"
            byte[]       bytes  = { 2, 1, 4, 3, 3, (byte)216, (byte)254, 19, 22, (byte)216, (byte)254, 0, (byte)242, 3, 103, 111, 111, 46, 103, 108, 47, 104, 113, 66, 88, 69, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            BeaconParser parser = new BeaconParser().SetBeaconLayout("s:0-1=fed8,m:2-2=00,p:3-3:-41,i:4-21v");

            Beacon uriBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("UriBeacon should be not null if parsed successfully", uriBeacon);
            AssertEx.AreEqual("UriBeacon identifier length should be correct",
                              14,
                              uriBeacon.Id1.ToByteArray().Length);
            String urlString = UrlBeaconUrlCompressor.Uncompress(uriBeacon.Id1.ToByteArray());

            AssertEx.AreEqual("URL should be decompressed successfully", "https://goo.gl/hqBXE1", urlString);
        }
示例#19
0
        public void TestParsesBeaconMissingDataField()
        {
            var bytes  = HexStringToByteArray("02011a1aff1801beac2f234454cf6d4a0fadf2f4911ba9ffa600010002c5000000");
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25");
            var beacon = parser.FromScanData(bytes, -55, null);

            AssertEx.AreEqual("mRssi should be as passed in", -55, beacon.Rssi);
            AssertEx.AreEqual("uuid should be parsed", "2f234454-cf6d-4a0f-adf2-f4911ba9ffa6", beacon.GetIdentifier(0).ToString());
            AssertEx.AreEqual("id2 should be parsed", "1", beacon.GetIdentifier(1).ToString());
            AssertEx.AreEqual("id3 should be parsed", "2", beacon.GetIdentifier(2).ToString());
            AssertEx.AreEqual("txPower should be parsed", -59, beacon.TxPower);
            AssertEx.AreEqual("manufacturer should be parsed", 0x118, beacon.Manufacturer);
            AssertEx.AreEqual("missing data field zero should be zero", Convert.ToInt64(0), Convert.ToInt64(beacon.DataFields[0]));
        }
        public void TestDetectsGattBeacon2WithShortIdentifier()
        {
            byte[]       bytes      = HexStringToByteArray("020106030334121516341210ec007261646975736e6574776f726b7307000000000000000000000000000000000000000000000000000000000000000000");
            BeaconParser parser     = new BeaconParser().SetBeaconLayout("s:0-1=1234,m:2-2=10,p:3-3:-41,i:4-20v");
            Beacon       gattBeacon = parser.FromScanData(bytes, -55, null, DateTime.UtcNow.Ticks);

            AssertEx.NotNull("GattBeacon should be not null if parsed successfully", gattBeacon);
            AssertEx.AreEqual("GattBeacon identifier length should be adjusted smaller if packet is short",
                              16,
                              gattBeacon.Id1.ToByteArray().Length);
            AssertEx.AreEqual("GattBeacon identifier should have proper first byte",
                              (byte)0x00,
                              gattBeacon.Id1.ToByteArray()[0]);
            AssertEx.AreEqual("GattBeacon identifier should have proper second to last byte",
                              (byte)0x73,
                              gattBeacon.Id1.ToByteArray()[14]);
            AssertEx.AreEqual("GattBeacon identifier should have proper last byte",
                              (byte)0x07,
                              gattBeacon.Id1.ToByteArray()[15]);
        }
示例#21
0
        public void TestCanParseLongDataTypeOfDifferentSize()
        {
            // Create a beacon parser
            var parser = new BeaconParser();

            parser.SetBeaconLayout("m:2-3=0118,i:4-7,p:8-8,d:9-16,d:18-21,d:22-25");

            // Generate sample beacon for test purpose.
            var sampleData = new List <Java.Lang.Long>();
            var now        = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            sampleData.Add(new Java.Lang.Long(now));
            sampleData.Add(new Java.Lang.Long(1234L));
            sampleData.Add(new Java.Lang.Long(9876L));
            var beacon = new Beacon.Builder()
                         .SetManufacturer(0x0118)
                         .SetId1("02646576656c6f7065722e636f6d")
                         .SetTxPower(-59)
                         .SetDataFields(sampleData)
                         .Build();

            AssertEx.AreEqual("beacon contains a valid data on index 0", now, beacon.DataFields[0].LongValue());

            // Make byte array
            byte[] headerBytes = HexStringToByteArray("1bff1801");
            byte[] bodyBytes   = parser.GetBeaconAdvertisementData(beacon);
            byte[] bytes       = new byte[headerBytes.Length + bodyBytes.Length];
            Array.Copy(headerBytes, 0, bytes, 0, headerBytes.Length);
            Array.Copy(bodyBytes, 0, bytes, headerBytes.Length, bodyBytes.Length);

            // Try parsing the byte array
            Beacon parsedBeacon = parser.FromScanData(bytes, -59, null);

            AssertEx.AreEqual("parsed beacon should contain a valid data on index 0", now, parsedBeacon.DataFields[0].LongValue());
            AssertEx.AreEqual("parsed beacon should contain a valid data on index 1", Convert.ToInt64(1234L), parsedBeacon.DataFields[1].LongValue());
            AssertEx.AreEqual("parsed beacon should contain a valid data on index 2", Convert.ToInt64(9876L), parsedBeacon.DataFields[2].LongValue());
        }