Skip to content

Commit 459eb1d

Browse files
committed
Starting to abstract more so we can support more beacon types
1 parent cb43be7 commit 459eb1d

11 files changed

Lines changed: 136 additions & 84 deletions

File tree

library/src/main/java/uk/co/alt236/bluetoothlelib/device/BluetoothLeDevice.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,6 @@ public String getBluetoothDeviceClassName() {
216216
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
217217
}
218218

219-
/**
220-
* Gets the bluetooth device major class name.
221-
*
222-
* @return the bluetooth device major class name
223-
*/
224-
public String getBluetoothDeviceMajorClassName() {
225-
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
226-
}
227-
228219
public Set<BluetoothService> getBluetoothDeviceKnownSupportedServices() {
229220
if (mServiceSet == null) {
230221
synchronized (this) {
@@ -244,6 +235,15 @@ public Set<BluetoothService> getBluetoothDeviceKnownSupportedServices() {
244235
return mServiceSet;
245236
}
246237

238+
/**
239+
* Gets the bluetooth device major class name.
240+
*
241+
* @return the bluetooth device major class name
242+
*/
243+
public String getBluetoothDeviceMajorClassName() {
244+
return BluetoothClassResolver.resolveMajorDeviceClass(mDevice.getBluetoothClass().getMajorDeviceClass());
245+
}
246+
247247
/**
248248
* Gets the device.
249249
*
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package uk.co.alt236.bluetoothlelib.device.beacon;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
*
7+
*/
8+
public abstract class BeaconManufacturerData {
9+
private final BeaconType mBeaconType;
10+
private final byte[] mData;
11+
12+
protected BeaconManufacturerData(final BeaconType expectedType, final byte[] data){
13+
if (BeaconUtils.getBeaconType(data) != expectedType) {
14+
throw new IllegalArgumentException(
15+
"Manufacturer record '"
16+
+ Arrays.toString(data)
17+
+ "' is not from a " + expectedType);
18+
}
19+
20+
this.mData = data;
21+
this.mBeaconType = expectedType;
22+
}
23+
24+
public BeaconType getBeaconType(){
25+
return mBeaconType;
26+
}
27+
28+
public byte[] getData(){
29+
return mData;
30+
}
31+
}

library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
*/
66
public enum BeaconType {
77
NOT_A_BEACON,
8-
IBEACON
8+
IBEACON,
99
}

library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ private BeaconUtils(){
2121
* @return the {@link BeaconType}
2222
*/
2323
public static BeaconType getBeaconType(final byte[] manufacturerData) {
24-
if (manufacturerData == null) {
24+
if (manufacturerData == null || manufacturerData.length == 0) {
2525
return BeaconType.NOT_A_BEACON;
2626
}
2727

library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconDevice.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public class IBeaconDevice extends BluetoothLeDevice implements BeaconDevice{
2525
*/
2626
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
2727
super(device, rssi, scanRecord, 0);
28-
validate();
2928
mIBeaconData = new IBeaconManufacturerData(this);
3029
}
3130

@@ -40,7 +39,6 @@ public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[]
4039
*/
4140
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
4241
super(device, rssi, scanRecord, timestamp);
43-
validate();
4442
mIBeaconData = new IBeaconManufacturerData(this);
4543
}
4644

@@ -53,13 +51,11 @@ public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[]
5351
*/
5452
public IBeaconDevice(final BluetoothLeDevice device) {
5553
super(device);
56-
validate();
5754
mIBeaconData = new IBeaconManufacturerData(this);
5855
}
5956

6057
private IBeaconDevice(final Parcel in) {
6158
super(in);
62-
validate();
6359
mIBeaconData = new IBeaconManufacturerData(this);
6460
}
6561

@@ -143,10 +139,4 @@ public int getMinor() {
143139
public String getUUID() {
144140
return getIBeaconData().getUUID();
145141
}
146-
147-
private void validate() {
148-
if (BeaconUtils.getBeaconType(this) != BeaconType.IBEACON) {
149-
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
150-
}
151-
}
152142
}

library/src/main/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconManufacturerData.java

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
66
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
7+
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
78
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
8-
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconUtils;
99
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
1010

1111
/**
@@ -45,8 +45,7 @@
4545
* @author Alexandros Schillings
4646
*/
4747

48-
public final class IBeaconManufacturerData {
49-
private final byte[] mData;
48+
public final class IBeaconManufacturerData extends BeaconManufacturerData{
5049
private final int mCalibratedTxPower;
5150
private final int mCompanyIdentidier;
5251
private final int mIBeaconAdvertisment;
@@ -71,24 +70,17 @@ public IBeaconManufacturerData(final BluetoothLeDevice device) {
7170
* @throws IllegalArgumentException if the data is not from an iBeacon.
7271
*/
7372
public IBeaconManufacturerData(final byte[] manufacturerData) {
74-
mData = manufacturerData;
73+
super(BeaconType.IBEACON, manufacturerData);
7574

76-
if (BeaconUtils.getBeaconType(mData) != BeaconType.IBEACON) {
77-
throw new IllegalArgumentException(
78-
"Manufacturer record '"
79-
+ Arrays.toString(manufacturerData)
80-
+ "' is not from an iBeacon.");
81-
}
82-
83-
final byte[] intArray = Arrays.copyOfRange(mData, 0, 2);
75+
final byte[] intArray = Arrays.copyOfRange(manufacturerData, 0, 2);
8476
ByteUtils.invertArray(intArray);
8577

8678
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(intArray);
87-
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4));
88-
mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(mData, 4, 20));
89-
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
90-
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
91-
mCalibratedTxPower = mData[24];
79+
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 2, 4));
80+
mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 4, 20));
81+
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 20, 22));
82+
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 22, 24));
83+
mCalibratedTxPower = manufacturerData[24];
9284
}
9385

9486
/**

library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/BeaconUtilsTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
*/
88
public class BeaconUtilsTest extends TestCase {
99

10-
public void testGetBeaconTypeInvalid() throws Exception {
11-
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
12-
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
13-
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
14-
}
15-
1610
public void testGetBeaconTypeIBeacon() throws Exception {
1711
assertEquals(BeaconType.IBEACON, BeaconUtils.getBeaconType(new byte[]{
1812
0x4C, 0x00, 0x02, 0x15, 0x00, // <- Magic iBeacon header
@@ -22,4 +16,10 @@ public void testGetBeaconTypeIBeacon() throws Exception {
2216
0x00, 0x00, 0x00, 0x00, 0x00
2317
}));
2418
}
19+
20+
public void testGetBeaconTypeInvalid() throws Exception {
21+
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType((byte[]) null));
22+
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[0]));
23+
assertEquals(BeaconType.NOT_A_BEACON, BeaconUtils.getBeaconType(new byte[25]));
24+
}
2525
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
2+
3+
import junit.framework.TestCase;
4+
5+
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
6+
7+
/**
8+
*
9+
*/
10+
public class IBeaconManufacturerDataTest extends TestCase {
11+
private static final byte[] NON_BEACON =
12+
{2, 1, 26, 11, -1, 76, 0, 9, 6, 3, -32, -64, -88,
13+
1, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
14+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
15+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
16+
17+
public void testNonIBeaconData() throws Exception{
18+
try {
19+
BeaconManufacturerData data = new IBeaconManufacturerData(NON_BEACON);
20+
fail("Should have thrown an exception");
21+
} catch (final IllegalArgumentException e){
22+
// EXPECTED
23+
}
24+
25+
try {
26+
BeaconManufacturerData data = new IBeaconManufacturerData((byte[]) null);
27+
fail("Should have thrown an exception");
28+
} catch (final IllegalArgumentException e){
29+
// EXPECTED
30+
}
31+
32+
try {
33+
BeaconManufacturerData data = new IBeaconManufacturerData(new byte[0]);
34+
fail("Should have thrown an exception");
35+
} catch (final IllegalArgumentException e){
36+
// EXPECTED
37+
}
38+
}
39+
}

library/src/test/java/uk/co/alt236/bluetoothlelib/device/beacon/ibeacon/IBeaconUtilsTest.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@
77
*/
88
public class IBeaconUtilsTest extends TestCase {
99

10+
public void testCalculateUuidString() throws Exception {
11+
assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
12+
assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
13+
assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
14+
assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
15+
assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
16+
assertEquals(
17+
"00000000-0000-0000-0000-00",
18+
IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
19+
}
20+
1021
public void testGetDistanceDescriptor() throws Exception {
1122
assertEquals(IBeaconDistanceDescriptor.UNKNOWN, IBeaconUtils.getDistanceDescriptor(-1));
1223

@@ -18,15 +29,4 @@ public void testGetDistanceDescriptor() throws Exception {
1829

1930
assertEquals(IBeaconDistanceDescriptor.FAR, IBeaconUtils.getDistanceDescriptor(3));
2031
}
21-
22-
public void testCalculateUuidString() throws Exception {
23-
assertEquals("00", IBeaconUtils.calculateUuidString(new byte[]{0}));
24-
assertEquals("0a", IBeaconUtils.calculateUuidString(new byte[]{10}));
25-
assertEquals("0f", IBeaconUtils.calculateUuidString(new byte[]{15}));
26-
assertEquals("10", IBeaconUtils.calculateUuidString(new byte[]{16}));
27-
assertEquals("7f", IBeaconUtils.calculateUuidString(new byte[]{127}));
28-
assertEquals(
29-
"00000000-0000-0000-0000-00",
30-
IBeaconUtils.calculateUuidString(new byte[]{0,0,0,0,0,0,0,0,0,0,0}));
31-
}
3232
}

library/src/test/java/uk/co/alt236/bluetoothlelib/util/AdRecordUtilsTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ public void testParseScanRecordAsSparseArray() throws Exception {
4949
//
5050
// Cannot be tested here as it relies on Android code...
5151
//
52-
// final SparseArray<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
53-
// assertNotNull(adRecords);
54-
// assertEquals(2, adRecords.size());
55-
// assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
56-
// assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
52+
// final SparseArray<AdRecord> adRecords = AdRecordUtils.parseScanRecordAsSparseArray(NON_IBEACON);
53+
// assertNotNull(adRecords);
54+
// assertEquals(2, adRecords.size());
55+
// assertEquals(AdRecord.TYPE_FLAGS, adRecords.get(AdRecord.TYPE_FLAGS).getType());
56+
// assertEquals(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA, adRecords.get(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getType());
5757
}
5858
}

0 commit comments

Comments
 (0)