package uk.co.alt236.bluetoothlelib.device.beacon.ibeacon;
import java.util.Arrays;
import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconManufacturerData;
import uk.co.alt236.bluetoothlelib.device.beacon.BeaconType;
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
/**
* Parses the Manufactured Data field of an iBeacon
* <p>
* The parsing is based on the following schema:
* <pre>
* 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
* </pre>
* @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;
}
}