package com.blakequ.bluetooth_manager_lib.device.ibeacon; import com.blakequ.bluetooth_manager_lib.device.BeaconManufacturerData; import com.blakequ.bluetooth_manager_lib.device.BeaconType; import com.blakequ.bluetooth_manager_lib.device.BluetoothLeDevice; import com.blakequ.bluetooth_manager_lib.device.adrecord.AdRecord; import com.blakequ.bluetooth_manager_lib.util.ByteUtils; import java.util.Arrays; /** * Parses the Manufactured Data field of an iBeacon *

* The parsing is based on the following schema: *

 * Byte|Value
 * -------------------------------------------------
 * 0	4C - Byte 1 (LSB) of Company identifier code
 * 1	00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple)
 * 2	02 - Byte 0 of iBeacon advertisement indicator
 * 3	15 - Byte 1 of iBeacon advertisement indicator
 * 4	e2 |\
 * 5	c5 |\\
 * 6	6d |#\\
 * 7	b5 |##\\
 * 8	df |###\\
 * 9	fb |####\\
 * 10	48 |#####\\
 * 11	d2 |#####|| iBeacon
 * 12	b0 |#####|| Proximity UUID
 * 13	60 |#####//
 * 14	d0 |####//
 * 15	f5 |###//
 * 16	a7 |##//
 * 17	10 |#//
 * 18	96 |//
 * 19	e0 |/
 * 20	00 - major
 * 21	00
 * 22	00 - minor
 * 23	00
 * 24	c5 - The 2's complement of the calibrated Tx Power
 * 
* @author Alexandros Schillings */ public final class IBeaconManufacturerData extends BeaconManufacturerData { private final int mCalibratedTxPower; private final int mCompanyIdentidier; private final int mIBeaconAdvertisment; private final int mMajor; private final int mMinor; private final String mUUID; /** * Instantiates a new iBeacon manufacturer data object. * * @param device a {@link BluetoothLeDevice} * @throws IllegalArgumentException if the data is not from an iBeacon. */ public IBeaconManufacturerData(final BluetoothLeDevice device) { this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData()); } /** * Instantiates a new iBeacon manufacturer data object. * * @param manufacturerData the {@link AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array * @throws IllegalArgumentException if the data is not from an iBeacon. */ public IBeaconManufacturerData(final byte[] manufacturerData) { super(BeaconType.IBEACON, manufacturerData); final byte[] intArray = Arrays.copyOfRange(manufacturerData, 0, 2); ByteUtils.invertArray(intArray); mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(intArray); mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 2, 4)); mUUID = IBeaconUtils.calculateUuidString(Arrays.copyOfRange(manufacturerData, 4, 20)); mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 20, 22)); mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(manufacturerData, 22, 24)); mCalibratedTxPower = manufacturerData[24]; } /** * Gets the calibrated TX power of the iBeacon device as reported. * * @return the calibrated TX power */ public int getCalibratedTxPower() { return mCalibratedTxPower; } /** * Gets the iBeacon company identifier. * * @return the company identifier */ public int getCompanyIdentifier() { return mCompanyIdentidier; } public int getIBeaconAdvertisement() { return mIBeaconAdvertisment; } /** * Gets the iBeacon Major value. * * @return the Major value */ public int getMajor() { return mMajor; } /** * Gets the iBeacon Minor value. * * @return the Minor value */ public int getMinor() { return mMinor; } /** * Gets the iBeacon UUID. * * @return the UUID */ public String getUUID() { return mUUID; } }