Full code reformat
This commit is contained in:
@@ -1,18 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<manifest
|
||||
package="uk.co.alt236.bluetoothlelib"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionCode="2"
|
||||
android:versionName="0.0.2" >
|
||||
android:versionName="0.0.2">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="18"
|
||||
android:targetSdkVersion="18" />
|
||||
android:targetSdkVersion="18"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
android:theme="@style/AppTheme">
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -1,5 +1,10 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@@ -10,12 +15,9 @@ import uk.co.alt236.bluetoothlelib.resolvers.BluetoothClassResolver;
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.LimitedLinkHashMap;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
// TODO: Auto-generated Javadoc
|
||||
|
||||
/**
|
||||
* This is a wrapper around the default BluetoothDevice object
|
||||
* As BluetoothDevice is final it cannot be extended, so to get it you
|
||||
@@ -23,373 +25,372 @@ import android.os.Parcelable;
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*/
|
||||
public class BluetoothLeDevice implements Parcelable{
|
||||
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
|
||||
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
|
||||
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
|
||||
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
|
||||
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
|
||||
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
|
||||
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
|
||||
protected static final int MAX_RSSI_LOG_SIZE = 10;
|
||||
public class BluetoothLeDevice implements Parcelable {
|
||||
/**
|
||||
* The Constant CREATOR.
|
||||
*/
|
||||
public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() {
|
||||
public BluetoothLeDevice createFromParcel(final Parcel in) {
|
||||
return new BluetoothLeDevice(in);
|
||||
}
|
||||
|
||||
private final AdRecordStore mRecordStore;
|
||||
private final BluetoothDevice mDevice;
|
||||
private final Map<Long, Integer> mRssiLog;
|
||||
private final byte[] mScanRecord;
|
||||
private final int mFirstRssi;
|
||||
private final long mFirstTimestamp;
|
||||
public BluetoothLeDevice[] newArray(final int size) {
|
||||
return new BluetoothLeDevice[size];
|
||||
}
|
||||
};
|
||||
protected static final int MAX_RSSI_LOG_SIZE = 10;
|
||||
private static final String PARCEL_EXTRA_BLUETOOTH_DEVICE = "bluetooth_device";
|
||||
private static final String PARCEL_EXTRA_CURRENT_RSSI = "current_rssi";
|
||||
private static final String PARCEL_EXTRA_CURRENT_TIMESTAMP = "current_timestamp";
|
||||
private static final String PARCEL_EXTRA_DEVICE_RSSI_LOG = "device_rssi_log";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD = "device_scanrecord";
|
||||
private static final String PARCEL_EXTRA_DEVICE_SCANRECORD_STORE = "device_scanrecord_store";
|
||||
private static final String PARCEL_EXTRA_FIRST_RSSI = "device_first_rssi";
|
||||
private static final String PARCEL_EXTRA_FIRST_TIMESTAMP = "first_timestamp";
|
||||
private static final long LOG_INVALIDATION_THRESHOLD = 10 * 1000;
|
||||
private final AdRecordStore mRecordStore;
|
||||
private final BluetoothDevice mDevice;
|
||||
private final Map<Long, Integer> mRssiLog;
|
||||
private final byte[] mScanRecord;
|
||||
private final int mFirstRssi;
|
||||
private final long mFirstTimestamp;
|
||||
private int mCurrentRssi;
|
||||
private long mCurrentTimestamp;
|
||||
|
||||
private int mCurrentRssi;
|
||||
private long mCurrentTimestamp;
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device a standard android Bluetooth device
|
||||
* @param rssi the RSSI value of the Bluetooth device
|
||||
* @param scanRecord the scan record of the device
|
||||
* @param timestamp the timestamp of the RSSI reading
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
mDevice = device;
|
||||
mFirstRssi = rssi;
|
||||
mFirstTimestamp = timestamp;
|
||||
mRecordStore = new AdRecordStore(AdRecordUtils.parseScanRecordAsSparseArray(scanRecord));
|
||||
mScanRecord = scanRecord;
|
||||
mRssiLog = new LimitedLinkHashMap<Long, Integer>(MAX_RSSI_LOG_SIZE);
|
||||
updateRssiReading(timestamp, rssi);
|
||||
}
|
||||
|
||||
/** The Constant CREATOR. */
|
||||
public static final Parcelable.Creator<BluetoothLeDevice> CREATOR = new Parcelable.Creator<BluetoothLeDevice>() {
|
||||
public BluetoothLeDevice createFromParcel(final Parcel in) {
|
||||
return new BluetoothLeDevice(in);
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device the device
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothLeDevice device) {
|
||||
mCurrentRssi = device.getRssi();
|
||||
mCurrentTimestamp = device.getTimestamp();
|
||||
mDevice = device.getDevice();
|
||||
mFirstRssi = device.getFirstRssi();
|
||||
mFirstTimestamp = device.getFirstTimestamp();
|
||||
mRecordStore = new AdRecordStore(
|
||||
AdRecordUtils.parseScanRecordAsSparseArray(device.getScanRecord()));
|
||||
mRssiLog = device.getRssiLog();
|
||||
mScanRecord = device.getScanRecord();
|
||||
}
|
||||
|
||||
public BluetoothLeDevice[] newArray(final int size) {
|
||||
return new BluetoothLeDevice[size];
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Instantiates a new bluetooth le device.
|
||||
*
|
||||
* @param in the in
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected BluetoothLeDevice(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device a standard android Bluetooth device
|
||||
* @param rssi the RSSI value of the Bluetooth device
|
||||
* @param scanRecord the scan record of the device
|
||||
* @param timestamp the timestamp of the RSSI reading
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp){
|
||||
mDevice = device;
|
||||
mFirstRssi = rssi;
|
||||
mFirstTimestamp = timestamp;
|
||||
mRecordStore = new AdRecordStore(AdRecordUtils.parseScanRecordAsSparseArray(scanRecord));
|
||||
mScanRecord = scanRecord;
|
||||
mRssiLog = new LimitedLinkHashMap<Long, Integer>(MAX_RSSI_LOG_SIZE);
|
||||
updateRssiReading(timestamp, rssi);
|
||||
}
|
||||
mCurrentRssi = b.getInt(PARCEL_EXTRA_CURRENT_RSSI, 0);
|
||||
mCurrentTimestamp = b.getLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, 0);
|
||||
mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE);
|
||||
mFirstRssi = b.getInt(PARCEL_EXTRA_FIRST_RSSI, 0);
|
||||
mFirstTimestamp = b.getLong(PARCEL_EXTRA_FIRST_TIMESTAMP, 0);
|
||||
mRecordStore = b.getParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE);
|
||||
mRssiLog = (Map<Long, Integer>) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
|
||||
mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device.
|
||||
*
|
||||
* @param device the device
|
||||
*/
|
||||
public BluetoothLeDevice(final BluetoothLeDevice device) {
|
||||
mCurrentRssi = device.getRssi();
|
||||
mCurrentTimestamp = device.getTimestamp();
|
||||
mDevice = device.getDevice();
|
||||
mFirstRssi = device.getFirstRssi();
|
||||
mFirstTimestamp = device.getFirstTimestamp();
|
||||
mRecordStore = new AdRecordStore(
|
||||
AdRecordUtils.parseScanRecordAsSparseArray(device.getScanRecord()));
|
||||
mRssiLog = device.getRssiLog();
|
||||
mScanRecord = device.getScanRecord();
|
||||
}
|
||||
/**
|
||||
* Adds the to rssi log.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
private void addToRssiLog(final long timestamp, final int rssiReading) {
|
||||
synchronized (mRssiLog) {
|
||||
if (timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD) {
|
||||
mRssiLog.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new bluetooth le device.
|
||||
*
|
||||
* @param in the in
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected BluetoothLeDevice(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mCurrentRssi = rssiReading;
|
||||
mCurrentTimestamp = timestamp;
|
||||
mRssiLog.put(timestamp, rssiReading);
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentRssi = b.getInt(PARCEL_EXTRA_CURRENT_RSSI, 0);
|
||||
mCurrentTimestamp = b.getLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, 0);
|
||||
mDevice = b.getParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE);
|
||||
mFirstRssi = b.getInt(PARCEL_EXTRA_FIRST_RSSI, 0);
|
||||
mFirstTimestamp = b.getLong(PARCEL_EXTRA_FIRST_TIMESTAMP, 0);
|
||||
mRecordStore = b.getParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE);
|
||||
mRssiLog = (Map<Long, Integer>) b.getSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG);
|
||||
mScanRecord = b.getByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to rssi log.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
private void addToRssiLog(final long timestamp, final int rssiReading){
|
||||
synchronized (mRssiLog) {
|
||||
if(timestamp - mCurrentTimestamp > LOG_INVALIDATION_THRESHOLD){
|
||||
mRssiLog.clear();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final BluetoothLeDevice other = (BluetoothLeDevice) obj;
|
||||
if (mCurrentRssi != other.mCurrentRssi)
|
||||
return false;
|
||||
if (mCurrentTimestamp != other.mCurrentTimestamp)
|
||||
return false;
|
||||
if (mDevice == null) {
|
||||
if (other.mDevice != null)
|
||||
return false;
|
||||
} else if (!mDevice.equals(other.mDevice))
|
||||
return false;
|
||||
if (mFirstRssi != other.mFirstRssi)
|
||||
return false;
|
||||
if (mFirstTimestamp != other.mFirstTimestamp)
|
||||
return false;
|
||||
if (mRecordStore == null) {
|
||||
if (other.mRecordStore != null)
|
||||
return false;
|
||||
} else if (!mRecordStore.equals(other.mRecordStore))
|
||||
return false;
|
||||
if (mRssiLog == null) {
|
||||
if (other.mRssiLog != null)
|
||||
return false;
|
||||
} else if (!mRssiLog.equals(other.mRssiLog))
|
||||
return false;
|
||||
if (!Arrays.equals(mScanRecord, other.mScanRecord))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mCurrentRssi = rssiReading;
|
||||
mCurrentTimestamp = timestamp;
|
||||
mRssiLog.put(timestamp, rssiReading);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets the ad record store.
|
||||
*
|
||||
* @return the ad record store
|
||||
*/
|
||||
public AdRecordStore getAdRecordStore() {
|
||||
return mRecordStore;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Gets the address.
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress() {
|
||||
return mDevice.getAddress();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final BluetoothLeDevice other = (BluetoothLeDevice) obj;
|
||||
if (mCurrentRssi != other.mCurrentRssi)
|
||||
return false;
|
||||
if (mCurrentTimestamp != other.mCurrentTimestamp)
|
||||
return false;
|
||||
if (mDevice == null) {
|
||||
if (other.mDevice != null)
|
||||
return false;
|
||||
} else if (!mDevice.equals(other.mDevice))
|
||||
return false;
|
||||
if (mFirstRssi != other.mFirstRssi)
|
||||
return false;
|
||||
if (mFirstTimestamp != other.mFirstTimestamp)
|
||||
return false;
|
||||
if (mRecordStore == null) {
|
||||
if (other.mRecordStore != null)
|
||||
return false;
|
||||
} else if (!mRecordStore.equals(other.mRecordStore))
|
||||
return false;
|
||||
if (mRssiLog == null) {
|
||||
if (other.mRssiLog != null)
|
||||
return false;
|
||||
} else if (!mRssiLog.equals(other.mRssiLog))
|
||||
return false;
|
||||
if (!Arrays.equals(mScanRecord, other.mScanRecord))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Gets the bluetooth device bond state.
|
||||
*
|
||||
* @return the bluetooth device bond state
|
||||
*/
|
||||
public String getBluetoothDeviceBondState() {
|
||||
return resolveBondingState(mDevice.getBondState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the address.
|
||||
*
|
||||
* @return the address
|
||||
*/
|
||||
public String getAddress(){
|
||||
return mDevice.getAddress();
|
||||
}
|
||||
/**
|
||||
* Gets the bluetooth device class name.
|
||||
*
|
||||
* @return the bluetooth device class name
|
||||
*/
|
||||
public String getBluetoothDeviceClassName() {
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ad record store.
|
||||
*
|
||||
* @return the ad record store
|
||||
*/
|
||||
public AdRecordStore getAdRecordStore(){
|
||||
return mRecordStore;
|
||||
}
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
* @return the device
|
||||
*/
|
||||
public BluetoothDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device bond state.
|
||||
*
|
||||
* @return the bluetooth device bond state
|
||||
*/
|
||||
public String getBluetoothDeviceBondState(){
|
||||
return resolveBondingState(mDevice.getBondState());
|
||||
}
|
||||
/**
|
||||
* Gets the first rssi.
|
||||
*
|
||||
* @return the first rssi
|
||||
*/
|
||||
public int getFirstRssi() {
|
||||
return mFirstRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bluetooth device class name.
|
||||
*
|
||||
* @return the bluetooth device class name
|
||||
*/
|
||||
public String getBluetoothDeviceClassName(){
|
||||
return BluetoothClassResolver.resolveDeviceClass(mDevice.getBluetoothClass().getDeviceClass());
|
||||
}
|
||||
/**
|
||||
* Gets the first timestamp.
|
||||
*
|
||||
* @return the first timestamp
|
||||
*/
|
||||
public long getFirstTimestamp() {
|
||||
return mFirstTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the device.
|
||||
*
|
||||
* @return the device
|
||||
*/
|
||||
public BluetoothDevice getDevice() {
|
||||
return mDevice;
|
||||
}
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return mDevice.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first rssi.
|
||||
*
|
||||
* @return the first rssi
|
||||
*/
|
||||
public int getFirstRssi(){
|
||||
return mFirstRssi;
|
||||
}
|
||||
/**
|
||||
* Gets the rssi.
|
||||
*
|
||||
* @return the rssi
|
||||
*/
|
||||
public int getRssi() {
|
||||
return mCurrentRssi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first timestamp.
|
||||
*
|
||||
* @return the first timestamp
|
||||
*/
|
||||
public long getFirstTimestamp(){
|
||||
return mFirstTimestamp;
|
||||
}
|
||||
/**
|
||||
* Gets the rssi log.
|
||||
*
|
||||
* @return the rssi log
|
||||
*/
|
||||
protected Map<Long, Integer> getRssiLog() {
|
||||
synchronized (mRssiLog) {
|
||||
return mRssiLog;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
*
|
||||
* @return the name
|
||||
*/
|
||||
public String getName(){
|
||||
return mDevice.getName();
|
||||
}
|
||||
/**
|
||||
* Gets the running average rssi.
|
||||
*
|
||||
* @return the running average rssi
|
||||
*/
|
||||
public double getRunningAverageRssi() {
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
|
||||
/**
|
||||
* Gets the rssi.
|
||||
*
|
||||
* @return the rssi
|
||||
*/
|
||||
public int getRssi() {
|
||||
return mCurrentRssi;
|
||||
}
|
||||
synchronized (mRssiLog) {
|
||||
final Iterator<Long> it1 = mRssiLog.keySet().iterator();
|
||||
|
||||
/**
|
||||
* Gets the rssi log.
|
||||
*
|
||||
* @return the rssi log
|
||||
*/
|
||||
protected Map<Long, Integer> getRssiLog() {
|
||||
synchronized (mRssiLog) {
|
||||
return mRssiLog;
|
||||
}
|
||||
}
|
||||
while (it1.hasNext()) {
|
||||
count++;
|
||||
sum += mRssiLog.get(it1.next());
|
||||
}
|
||||
}
|
||||
// for(final Map.Entry<Long,Integer> e : mRssiLog.entrySet()){
|
||||
// count ++;
|
||||
// sum += e.getValue();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Gets the running average rssi.
|
||||
*
|
||||
* @return the running average rssi
|
||||
*/
|
||||
public double getRunningAverageRssi(){
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
if (count > 0) {
|
||||
return sum / count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
synchronized (mRssiLog) {
|
||||
final Iterator<Long> it1 = mRssiLog.keySet().iterator();
|
||||
}
|
||||
|
||||
while(it1.hasNext()){
|
||||
count ++;
|
||||
sum += mRssiLog.get(it1.next());
|
||||
}
|
||||
}
|
||||
// for(final Map.Entry<Long,Integer> e : mRssiLog.entrySet()){
|
||||
// count ++;
|
||||
// sum += e.getValue();
|
||||
// }
|
||||
/**
|
||||
* Gets the scan record.
|
||||
*
|
||||
* @return the scan record
|
||||
*/
|
||||
public byte[] getScanRecord() {
|
||||
return mScanRecord;
|
||||
}
|
||||
|
||||
if(count > 0){
|
||||
return sum/count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Gets the timestamp.
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return mCurrentTimestamp;
|
||||
}
|
||||
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + mCurrentRssi;
|
||||
result = prime * result + (int) (mCurrentTimestamp ^ (mCurrentTimestamp >>> 32));
|
||||
result = prime * result + ((mDevice == null) ? 0 : mDevice.hashCode());
|
||||
result = prime * result + mFirstRssi;
|
||||
result = prime * result + (int) (mFirstTimestamp ^ (mFirstTimestamp >>> 32));
|
||||
result = prime * result + ((mRecordStore == null) ? 0 : mRecordStore.hashCode());
|
||||
result = prime * result + ((mRssiLog == null) ? 0 : mRssiLog.hashCode());
|
||||
result = prime * result + Arrays.hashCode(mScanRecord);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the scan record.
|
||||
*
|
||||
* @return the scan record
|
||||
*/
|
||||
public byte[] getScanRecord() {
|
||||
return mScanRecord;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" + getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" + getBluetoothDeviceClassName() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timestamp.
|
||||
*
|
||||
* @return the timestamp
|
||||
*/
|
||||
public long getTimestamp(){
|
||||
return mCurrentTimestamp;
|
||||
}
|
||||
/**
|
||||
* Update rssi reading.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
public void updateRssiReading(final long timestamp, final int rssiReading) {
|
||||
addToRssiLog(timestamp, rssiReading);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + mCurrentRssi;
|
||||
result = prime * result + (int) (mCurrentTimestamp ^ (mCurrentTimestamp >>> 32));
|
||||
result = prime * result + ((mDevice == null) ? 0 : mDevice.hashCode());
|
||||
result = prime * result + mFirstRssi;
|
||||
result = prime * result + (int) (mFirstTimestamp ^ (mFirstTimestamp >>> 32));
|
||||
result = prime * result + ((mRecordStore == null) ? 0 : mRecordStore.hashCode());
|
||||
result = prime * result + ((mRssiLog == null) ? 0 : mRssiLog.hashCode());
|
||||
result = prime * result + Arrays.hashCode(mScanRecord);
|
||||
return result;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BluetoothLeDevice [mDevice=" + mDevice + ", mRssi=" + mFirstRssi + ", mScanRecord=" + ByteUtils.byteArrayToHexString(mScanRecord) + ", mRecordStore=" + mRecordStore + ", getBluetoothDeviceBondState()=" + getBluetoothDeviceBondState() + ", getBluetoothDeviceClassName()=" + getBluetoothDeviceClassName() + "]";
|
||||
}
|
||||
b.putByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD, mScanRecord);
|
||||
|
||||
/**
|
||||
* Update rssi reading.
|
||||
*
|
||||
* @param timestamp the timestamp
|
||||
* @param rssiReading the rssi reading
|
||||
*/
|
||||
public void updateRssiReading(final long timestamp, final int rssiReading){
|
||||
addToRssiLog(timestamp, rssiReading);
|
||||
}
|
||||
b.putInt(PARCEL_EXTRA_FIRST_RSSI, mFirstRssi);
|
||||
b.putInt(PARCEL_EXTRA_CURRENT_RSSI, mCurrentRssi);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
b.putLong(PARCEL_EXTRA_FIRST_TIMESTAMP, mFirstTimestamp);
|
||||
b.putLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, mCurrentTimestamp);
|
||||
|
||||
b.putByteArray(PARCEL_EXTRA_DEVICE_SCANRECORD, mScanRecord);
|
||||
b.putParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE, mDevice);
|
||||
b.putParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE, mRecordStore);
|
||||
b.putSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG, (Serializable) mRssiLog);
|
||||
|
||||
b.putInt(PARCEL_EXTRA_FIRST_RSSI, mFirstRssi);
|
||||
b.putInt(PARCEL_EXTRA_CURRENT_RSSI, mCurrentRssi);
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
b.putLong(PARCEL_EXTRA_FIRST_TIMESTAMP, mFirstTimestamp);
|
||||
b.putLong(PARCEL_EXTRA_CURRENT_TIMESTAMP, mCurrentTimestamp);
|
||||
|
||||
b.putParcelable(PARCEL_EXTRA_BLUETOOTH_DEVICE, mDevice);
|
||||
b.putParcelable(PARCEL_EXTRA_DEVICE_SCANRECORD_STORE, mRecordStore);
|
||||
b.putSerializable(PARCEL_EXTRA_DEVICE_RSSI_LOG, (Serializable) mRssiLog);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve bonding state.
|
||||
*
|
||||
* @param bondState the bond state
|
||||
* @return the string
|
||||
*/
|
||||
private static String resolveBondingState(final int bondState){
|
||||
switch (bondState){
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
return "Paired";
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
return "Pairing";
|
||||
case BluetoothDevice.BOND_NONE:
|
||||
return "Unbonded";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resolve bonding state.
|
||||
*
|
||||
* @param bondState the bond state
|
||||
* @return the string
|
||||
*/
|
||||
private static String resolveBondingState(final int bondState) {
|
||||
switch (bondState) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
return "Paired";
|
||||
case BluetoothDevice.BOND_BONDING:
|
||||
return "Pairing";
|
||||
case BluetoothDevice.BOND_NONE:
|
||||
return "Unbonded";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,143 +1,146 @@
|
||||
package uk.co.alt236.bluetoothlelib.device;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils.IBeaconDistanceDescriptor;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
|
||||
public class IBeaconDevice extends BluetoothLeDevice{
|
||||
import uk.co.alt236.bluetoothlelib.device.mfdata.IBeaconManufacturerData;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconDistanceDescriptor;
|
||||
import uk.co.alt236.bluetoothlelib.util.IBeaconUtils;
|
||||
|
||||
/** The m iBeacon data. */
|
||||
private final IBeaconManufacturerData mIBeaconData;
|
||||
public class IBeaconDevice extends BluetoothLeDevice {
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value
|
||||
* @param scanRecord the scanRecord
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||
super(device, rssi, scanRecord, 0);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
/**
|
||||
* The m iBeacon data.
|
||||
*/
|
||||
private final IBeaconManufacturerData mIBeaconData;
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value of the RSSI measurement
|
||||
* @param scanRecord the scan record
|
||||
* @param timestamp the timestamp of the RSSI measurement
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp){
|
||||
super(device, rssi, scanRecord, timestamp);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value
|
||||
* @param scanRecord the scanRecord
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||
super(device, rssi, scanRecord, 0);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will try to convert a {@link BluetoothLeDevice} into an
|
||||
* iBeacon Device.
|
||||
*
|
||||
* @param device the device
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothLeDevice device){
|
||||
super(device);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
/**
|
||||
* Instantiates a new iBeacon device.
|
||||
*
|
||||
* @param device the device
|
||||
* @param rssi the RSSI value of the RSSI measurement
|
||||
* @param scanRecord the scan record
|
||||
* @param timestamp the timestamp of the RSSI measurement
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothDevice device, final int rssi, final byte[] scanRecord, final long timestamp) {
|
||||
super(device, rssi, scanRecord, timestamp);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
private IBeaconDevice(final Parcel in) {
|
||||
super(in);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
/**
|
||||
* Will try to convert a {@link BluetoothLeDevice} into an
|
||||
* iBeacon Device.
|
||||
*
|
||||
* @param device the device
|
||||
* @throws IllegalArgumentException if the passed device is not an iBeacon
|
||||
*/
|
||||
public IBeaconDevice(final BluetoothLeDevice device) {
|
||||
super(device);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Accuracy of the reading in meters based on
|
||||
* a simple running average of the last {@link #MAX_RSSI_LOG_SIZE}
|
||||
* samples.
|
||||
*
|
||||
* @return the accuracy in meters
|
||||
*/
|
||||
public double getAccuracy(){
|
||||
return IBeaconUtils.calculateAccuracy(
|
||||
getCalibratedTxPower(),
|
||||
getRunningAverageRssi());
|
||||
}
|
||||
private IBeaconDevice(final Parcel in) {
|
||||
super(in);
|
||||
validate();
|
||||
mIBeaconData = new IBeaconManufacturerData(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower(){
|
||||
return getIBeaconData().getCalibratedTxPower();
|
||||
}
|
||||
/**
|
||||
* Gets the estimated Accuracy of the reading in meters based on
|
||||
* a simple running average of the last {@link #MAX_RSSI_LOG_SIZE}
|
||||
* samples.
|
||||
*
|
||||
* @return the accuracy in meters
|
||||
*/
|
||||
public double getAccuracy() {
|
||||
return IBeaconUtils.calculateAccuracy(
|
||||
getCalibratedTxPower(),
|
||||
getRunningAverageRssi());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier(){
|
||||
return getIBeaconData().getCompanyIdentifier();
|
||||
}
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower() {
|
||||
return getIBeaconData().getCalibratedTxPower();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the estimated Distance descriptor.
|
||||
*
|
||||
* @return the distance descriptor
|
||||
*/
|
||||
public IBeaconDistanceDescriptor getDistanceDescriptor(){
|
||||
return IBeaconUtils.getDistanceDescriptor(getAccuracy());
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier() {
|
||||
return getIBeaconData().getCompanyIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon manufacturing data.
|
||||
*
|
||||
* @return the iBeacon data
|
||||
*/
|
||||
public IBeaconManufacturerData getIBeaconData(){
|
||||
return mIBeaconData;
|
||||
}
|
||||
/**
|
||||
* Gets the estimated Distance descriptor.
|
||||
*
|
||||
* @return the distance descriptor
|
||||
*/
|
||||
public IBeaconDistanceDescriptor getDistanceDescriptor() {
|
||||
return IBeaconUtils.getDistanceDescriptor(getAccuracy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor(){
|
||||
return getIBeaconData().getMajor();
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon manufacturing data.
|
||||
*
|
||||
* @return the iBeacon data
|
||||
*/
|
||||
public IBeaconManufacturerData getIBeaconData() {
|
||||
return mIBeaconData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor(){
|
||||
return getIBeaconData().getMinor();
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor() {
|
||||
return getIBeaconData().getMajor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID(){
|
||||
return getIBeaconData().getUUID();
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor() {
|
||||
return getIBeaconData().getMinor();
|
||||
}
|
||||
|
||||
private void validate(){
|
||||
if(!IBeaconUtils.isThisAnIBeacon(this)){
|
||||
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID() {
|
||||
return getIBeaconData().getUUID();
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
if (!IBeaconUtils.isThisAnIBeacon(this)) {
|
||||
throw new IllegalArgumentException("Device " + getDevice() + " is not an iBeacon.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,243 +1,227 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
import java.util.Arrays;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by Dave Smith
|
||||
* Double Encore, Inc.
|
||||
*
|
||||
* <p/>
|
||||
* Expanded by Alexandros Schillings
|
||||
*/
|
||||
public final class AdRecord implements Parcelable{
|
||||
// 02 # Number of bytes that follow in first AD structure
|
||||
// 01 # Flags AD type
|
||||
// 1A # Flags value 0x1A = 000011010
|
||||
// bit 0 (OFF) LE Limited Discoverable Mode
|
||||
// bit 1 (ON) LE General Discoverable Mode
|
||||
// bit 2 (OFF) BR/EDR Not Supported
|
||||
// bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
|
||||
// bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
|
||||
// 1A # Number of bytes that follow in second (and last) AD structure
|
||||
// FF # Manufacturer specific data AD type
|
||||
// 4C 00 # Company identifier code (0x004C == Apple)
|
||||
// 02 # Byte 0 of iBeacon advertisement indicator
|
||||
// 15 # Byte 1 of iBeacon advertisement indicator
|
||||
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
|
||||
// 00 00 # major
|
||||
// 00 00 # minor
|
||||
// c5 # The 2's complement of the calibrated Tx Power
|
||||
public final class AdRecord implements Parcelable {
|
||||
// 02 # Number of bytes that follow in first AD structure
|
||||
// 01 # Flags AD type
|
||||
// 1A # Flags value 0x1A = 000011010
|
||||
// bit 0 (OFF) LE Limited Discoverable Mode
|
||||
// bit 1 (ON) LE General Discoverable Mode
|
||||
// bit 2 (OFF) BR/EDR Not Supported
|
||||
// bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
|
||||
// bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
|
||||
// 1A # Number of bytes that follow in second (and last) AD structure
|
||||
// FF # Manufacturer specific data AD type
|
||||
// 4C 00 # Company identifier code (0x004C == Apple)
|
||||
// 02 # Byte 0 of iBeacon advertisement indicator
|
||||
// 15 # Byte 1 of iBeacon advertisement indicator
|
||||
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon proximity uuid
|
||||
// 00 00 # major
|
||||
// 00 00 # minor
|
||||
// c5 # The 2's complement of the calibrated Tx Power
|
||||
|
||||
|
||||
private static final String PARCEL_RECORD_DATA = "record_data";
|
||||
private static final String PARCEL_RECORD_TYPE = "record_type";
|
||||
private static final String PARCEL_RECORD_LENGTH = "record_length";
|
||||
/**
|
||||
* General FLAGS
|
||||
* <p/>
|
||||
* Description: Flags
|
||||
* <p/>
|
||||
* Information:
|
||||
* Bit 0: LE Limited Discoverable Mode
|
||||
* Bit 1: LE General Discoverable Mode
|
||||
* Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
|
||||
* Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
|
||||
* Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bits 5-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_FLAGS = 0x01;
|
||||
// SERVICE
|
||||
public static final int TYPE_UUID16_INC = 0x02;
|
||||
public static final int TYPE_UUID16 = 0x03;
|
||||
public static final int TYPE_UUID32_INC = 0x04;
|
||||
public static final int TYPE_UUID32 = 0x05;
|
||||
public static final int TYPE_UUID128_INC = 0x06;
|
||||
public static final int TYPE_UUID128 = 0x07;
|
||||
// Local name
|
||||
public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
|
||||
public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
|
||||
// TX Power Level
|
||||
public static final int TYPE_TX_POWER_LEVEL = 0x0A;
|
||||
// SIMPLE PAIRING OPTIONAL OOB TAGS
|
||||
public static final int TYPE_DEVICE_CLASS = 0x0D;
|
||||
public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
|
||||
public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
|
||||
// SECURITY MANAGER TK VALUE
|
||||
public static final int TYPE_TK_VALUE = 0x10;
|
||||
/* SECURITY MANAGER OOB FLAGS
|
||||
*
|
||||
* Description: Flag (1 octet)
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: OOB Flags Field: (0 = OOB data not present, 1 = OOB data present)
|
||||
* Bit 1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1
|
||||
* Bit 2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bit 3: Address type (0 = Public Address, 1 = Random Address)
|
||||
* Bits 4-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
|
||||
/* SLAVE CONNECTION INTERVAL RANGE
|
||||
*
|
||||
* Description: Slave Connection Interval Range
|
||||
*
|
||||
* Information:
|
||||
* The first 2 octets defines the minimum value for the connection interval in the following manner:
|
||||
* connInterval min = Conn_Interval_Min * 1.25 ms
|
||||
* Conn_Interval_Min range: 0x0006 to 0x0C80
|
||||
* Value of 0xFFFF indicates no specific minimum.
|
||||
* Values outside the range are reserved. (excluding 0xFFFF)
|
||||
*
|
||||
* The second 2 octets defines the maximum value for the connection interval in the following manner:
|
||||
* connInterval max = Conn_Interval_Max * 1.25 ms
|
||||
* Conn_Interval_Max range: 0x0006 to 0x0C80
|
||||
* Conn_Interval_Max shall be equal to or greater
|
||||
* than the Conn_Interval_Min.
|
||||
* Value of 0xFFFF indicates no specific maximum.
|
||||
* Values outside the range are reserved (excluding 0xFFFF)
|
||||
*/
|
||||
public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
|
||||
// SERVICE SOLICITATION
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
|
||||
/* SERVICE DATA
|
||||
*
|
||||
* Description: Service Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
|
||||
*/
|
||||
public static final int TYPE_SERVICE_DATA = 0x16;
|
||||
/* MANUFACTURER SPECIFIC DATA
|
||||
*
|
||||
* Description: Manufacturer Specific Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
|
||||
*/
|
||||
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
|
||||
public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
|
||||
public AdRecord createFromParcel(final Parcel in) {
|
||||
return new AdRecord(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* General FLAGS
|
||||
*
|
||||
* Description: Flags
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: LE Limited Discoverable Mode
|
||||
* Bit 1: LE General Discoverable Mode
|
||||
* Bit 2: BR/EDR Not Supported (i.e. bit 37 of LMP Extended Feature bits Page 0)
|
||||
* Bit 3: Simultaneous LE and BR/EDR to Same Device Capable (Controller) (i.e. bit 49 of LMP Extended Feature bits Page 0)
|
||||
* Bit 4: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bits 5-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_FLAGS = 0x01;
|
||||
public AdRecord[] newArray(final int size) {
|
||||
return new AdRecord[size];
|
||||
}
|
||||
};
|
||||
private static final String PARCEL_RECORD_DATA = "record_data";
|
||||
private static final String PARCEL_RECORD_TYPE = "record_type";
|
||||
private static final String PARCEL_RECORD_LENGTH = "record_length";
|
||||
/* Model Object Definition */
|
||||
private final int mLength;
|
||||
private final int mType;
|
||||
private final byte[] mData;
|
||||
|
||||
// SERVICE
|
||||
public static final int TYPE_UUID16_INC = 0x02;
|
||||
public static final int TYPE_UUID16 = 0x03;
|
||||
public static final int TYPE_UUID32_INC = 0x04;
|
||||
public static final int TYPE_UUID32 = 0x05;
|
||||
public static final int TYPE_UUID128_INC = 0x06;
|
||||
public static final int TYPE_UUID128 = 0x07;
|
||||
public AdRecord(final int length, final int type, final byte[] data) {
|
||||
mLength = length;
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
// Local name
|
||||
public static final int TYPE_LOCAL_NAME_SHORT = 0x08;
|
||||
public static final int TYPE_LOCAL_NAME_COMPLETE = 0x09;
|
||||
public AdRecord(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mLength = b.getInt(PARCEL_RECORD_LENGTH);
|
||||
mType = b.getInt(PARCEL_RECORD_TYPE);
|
||||
mData = b.getByteArray(PARCEL_RECORD_DATA);
|
||||
}
|
||||
|
||||
// TX Power Level
|
||||
public static final int TYPE_TX_POWER_LEVEL = 0x0A;
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SIMPLE PAIRING OPTIONAL OOB TAGS
|
||||
public static final int TYPE_DEVICE_CLASS = 0x0D;
|
||||
public static final int TYPE_SIMPLE_PAIRING_HASH_C = 0x0E;
|
||||
public static final int TYPE_SIMPLE_PAIRING_RANDOMIZER_R = 0x0F;
|
||||
public byte[] getData() {
|
||||
return mData;
|
||||
}
|
||||
|
||||
// SECURITY MANAGER TK VALUE
|
||||
public static final int TYPE_TK_VALUE = 0x10;
|
||||
public String getHumanReadableType() {
|
||||
return getHumanReadableAdType(mType);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
/* SECURITY MANAGER OOB FLAGS
|
||||
*
|
||||
* Description: Flag (1 octet)
|
||||
*
|
||||
* Information:
|
||||
* Bit 0: OOB Flags Field: (0 = OOB data not present, 1 = OOB data present)
|
||||
* Bit 1: LE supported (Host) (i.e. bit 65 of LMP Extended Feature bits Page 1
|
||||
* Bit 2: Simultaneous LE and BR/EDR to Same Device Capable (Host) (i.e. bit 66 of LMP Extended Feature bits Page 1)
|
||||
* Bit 3: Address type (0 = Public Address, 1 = Random Address)
|
||||
* Bits 4-7 Reserved
|
||||
*/
|
||||
public static final int TYPE_SECURITY_MANAGER_OOB_FLAGS = 0x11;
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" + getHumanReadableType() + "]";
|
||||
}
|
||||
|
||||
/* SLAVE CONNECTION INTERVAL RANGE
|
||||
*
|
||||
* Description: Slave Connection Interval Range
|
||||
*
|
||||
* Information:
|
||||
* The first 2 octets defines the minimum value for the connection interval in the following manner:
|
||||
* connInterval min = Conn_Interval_Min * 1.25 ms
|
||||
* Conn_Interval_Min range: 0x0006 to 0x0C80
|
||||
* Value of 0xFFFF indicates no specific minimum.
|
||||
* Values outside the range are reserved. (excluding 0xFFFF)
|
||||
*
|
||||
* The second 2 octets defines the maximum value for the connection interval in the following manner:
|
||||
* connInterval max = Conn_Interval_Max * 1.25 ms
|
||||
* Conn_Interval_Max range: 0x0006 to 0x0C80
|
||||
* Conn_Interval_Max shall be equal to or greater
|
||||
* than the Conn_Interval_Min.
|
||||
* Value of 0xFFFF indicates no specific maximum.
|
||||
* Values outside the range are reserved (excluding 0xFFFF)
|
||||
*/
|
||||
public static final int TYPE_CONNECTION_INTERVAL_RANGE = 0x12;
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
// SERVICE SOLICITATION
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_16BIT = 0x14;
|
||||
public static final int TYPE_SERVICE_UUIDS_LIST_128BIT = 0x15;
|
||||
b.putInt(PARCEL_RECORD_LENGTH, mLength);
|
||||
b.putInt(PARCEL_RECORD_TYPE, mType);
|
||||
b.putByteArray(PARCEL_RECORD_DATA, mData);
|
||||
|
||||
/* SERVICE DATA
|
||||
*
|
||||
* Description: Service Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the 16 bit Service UUID followed by additional service data
|
||||
*/
|
||||
public static final int TYPE_SERVICE_DATA = 0x16;
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
|
||||
/* MANUFACTURER SPECIFIC DATA
|
||||
*
|
||||
* Description: Manufacturer Specific Data (2 or more octets)
|
||||
* Information: The first 2 octets contain the Company Identifier Code followed by additional manufacturer specific data
|
||||
*/
|
||||
public static final int TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
|
||||
|
||||
/* Model Object Definition */
|
||||
private final int mLength;
|
||||
private final int mType;
|
||||
private final byte[] mData;
|
||||
|
||||
|
||||
public static final Parcelable.Creator<AdRecord> CREATOR = new Parcelable.Creator<AdRecord>() {
|
||||
public AdRecord createFromParcel(final Parcel in) {
|
||||
return new AdRecord(in);
|
||||
}
|
||||
|
||||
public AdRecord[] newArray(final int size) {
|
||||
return new AdRecord[size];
|
||||
}
|
||||
};
|
||||
|
||||
public AdRecord(final int length, final int type, final byte[] data) {
|
||||
mLength = length;
|
||||
mType = type;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
public AdRecord(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mLength = b.getInt(PARCEL_RECORD_LENGTH);
|
||||
mType = b.getInt(PARCEL_RECORD_TYPE);
|
||||
mData = b.getByteArray(PARCEL_RECORD_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public byte[] getData(){
|
||||
return mData;
|
||||
}
|
||||
|
||||
public String getHumanReadableType(){
|
||||
return getHumanReadableAdType(mType);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecord [mLength=" + mLength + ", mType=" + mType + ", mData=" + Arrays.toString(mData) + ", getHumanReadableType()=" + getHumanReadableType() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle(getClass().getClassLoader());
|
||||
|
||||
b.putInt(PARCEL_RECORD_LENGTH, mLength);
|
||||
b.putInt(PARCEL_RECORD_TYPE, mType);
|
||||
b.putByteArray(PARCEL_RECORD_DATA, mData);
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
private static String getHumanReadableAdType(final int type){
|
||||
switch(type){
|
||||
case TYPE_CONNECTION_INTERVAL_RANGE:
|
||||
return "Slave Connection Interval Range";
|
||||
case TYPE_DEVICE_CLASS:
|
||||
return "Class of device";
|
||||
case TYPE_FLAGS:
|
||||
return "Flags";
|
||||
case TYPE_MANUFACTURER_SPECIFIC_DATA:
|
||||
return "Manufacturer Specific Data";
|
||||
case TYPE_LOCAL_NAME_COMPLETE:
|
||||
return "Name (Complete)";
|
||||
case TYPE_LOCAL_NAME_SHORT:
|
||||
return "Name (Short)";
|
||||
case TYPE_SECURITY_MANAGER_OOB_FLAGS:
|
||||
return "Security Manager OOB Flags";
|
||||
case TYPE_SERVICE_UUIDS_LIST_128BIT:
|
||||
return "Service UUIDs (128bit)";
|
||||
case TYPE_SERVICE_UUIDS_LIST_16BIT:
|
||||
return "Service UUIDs (16bit)";
|
||||
case TYPE_SERVICE_DATA:
|
||||
return "Service Data";
|
||||
case TYPE_SIMPLE_PAIRING_HASH_C:
|
||||
return "Simple Pairing Hash C";
|
||||
case TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
|
||||
return "Simple Pairing Randomizer R";
|
||||
case TYPE_TK_VALUE:
|
||||
return "TK Value";
|
||||
case TYPE_TX_POWER_LEVEL:
|
||||
return "Transmission Power Level";
|
||||
case TYPE_UUID128:
|
||||
return "Complete list of 128-bit UUIDs available";
|
||||
case TYPE_UUID128_INC:
|
||||
return "More 128-bit UUIDs available";
|
||||
case TYPE_UUID16:
|
||||
return "Complete list of 16-bit UUIDs available";
|
||||
case TYPE_UUID16_INC:
|
||||
return "More 16-bit UUIDs available";
|
||||
case TYPE_UUID32:
|
||||
return "Complete list of 32-bit UUIDs available";
|
||||
case TYPE_UUID32_INC:
|
||||
return "More 32-bit UUIDs available";
|
||||
default:
|
||||
return "Unknown AdRecord Structure: " + type;
|
||||
}
|
||||
}
|
||||
private static String getHumanReadableAdType(final int type) {
|
||||
switch (type) {
|
||||
case TYPE_CONNECTION_INTERVAL_RANGE:
|
||||
return "Slave Connection Interval Range";
|
||||
case TYPE_DEVICE_CLASS:
|
||||
return "Class of device";
|
||||
case TYPE_FLAGS:
|
||||
return "Flags";
|
||||
case TYPE_MANUFACTURER_SPECIFIC_DATA:
|
||||
return "Manufacturer Specific Data";
|
||||
case TYPE_LOCAL_NAME_COMPLETE:
|
||||
return "Name (Complete)";
|
||||
case TYPE_LOCAL_NAME_SHORT:
|
||||
return "Name (Short)";
|
||||
case TYPE_SECURITY_MANAGER_OOB_FLAGS:
|
||||
return "Security Manager OOB Flags";
|
||||
case TYPE_SERVICE_UUIDS_LIST_128BIT:
|
||||
return "Service UUIDs (128bit)";
|
||||
case TYPE_SERVICE_UUIDS_LIST_16BIT:
|
||||
return "Service UUIDs (16bit)";
|
||||
case TYPE_SERVICE_DATA:
|
||||
return "Service Data";
|
||||
case TYPE_SIMPLE_PAIRING_HASH_C:
|
||||
return "Simple Pairing Hash C";
|
||||
case TYPE_SIMPLE_PAIRING_RANDOMIZER_R:
|
||||
return "Simple Pairing Randomizer R";
|
||||
case TYPE_TK_VALUE:
|
||||
return "TK Value";
|
||||
case TYPE_TX_POWER_LEVEL:
|
||||
return "Transmission Power Level";
|
||||
case TYPE_UUID128:
|
||||
return "Complete list of 128-bit UUIDs available";
|
||||
case TYPE_UUID128_INC:
|
||||
return "More 128-bit UUIDs available";
|
||||
case TYPE_UUID16:
|
||||
return "Complete list of 16-bit UUIDs available";
|
||||
case TYPE_UUID16_INC:
|
||||
return "More 16-bit UUIDs available";
|
||||
case TYPE_UUID32:
|
||||
return "Complete list of 32-bit UUIDs available";
|
||||
case TYPE_UUID32_INC:
|
||||
return "More 32-bit UUIDs available";
|
||||
default:
|
||||
return "Unknown AdRecord Structure: " + type;
|
||||
}
|
||||
}
|
||||
}
|
||||
+127
-127
@@ -1,158 +1,158 @@
|
||||
package uk.co.alt236.bluetoothlelib.device.adrecord;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.util.AdRecordUtils;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.SparseArray;
|
||||
|
||||
/**
|
||||
* The Class AdRecordStore.
|
||||
*/
|
||||
public class AdRecordStore implements Parcelable{
|
||||
private final SparseArray<AdRecord> mAdRecords;
|
||||
private final String mLocalNameComplete;
|
||||
private final String mLocalNameShort;
|
||||
public class AdRecordStore implements Parcelable {
|
||||
public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() {
|
||||
public AdRecordStore createFromParcel(final Parcel in) {
|
||||
return new AdRecordStore(in);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<AdRecordStore> CREATOR = new Parcelable.Creator<AdRecordStore>() {
|
||||
public AdRecordStore createFromParcel(final Parcel in) {
|
||||
return new AdRecordStore(in);
|
||||
}
|
||||
public AdRecordStore[] newArray(final int size) {
|
||||
return new AdRecordStore[size];
|
||||
}
|
||||
};
|
||||
private final SparseArray<AdRecord> mAdRecords;
|
||||
private final String mLocalNameComplete;
|
||||
private final String mLocalNameShort;
|
||||
|
||||
public AdRecordStore[] newArray(final int size) {
|
||||
return new AdRecordStore[size];
|
||||
}
|
||||
};
|
||||
public AdRecordStore(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mAdRecords = b.getSparseParcelableArray("records_array");
|
||||
mLocalNameComplete = b.getString("local_name_complete");
|
||||
mLocalNameShort = b.getString("local_name_short");
|
||||
}
|
||||
|
||||
public AdRecordStore(final Parcel in) {
|
||||
final Bundle b = in.readBundle(getClass().getClassLoader());
|
||||
mAdRecords = b.getSparseParcelableArray("records_array");
|
||||
mLocalNameComplete = b.getString("local_name_complete");
|
||||
mLocalNameShort = b.getString("local_name_short");
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device Ad Record Store.
|
||||
*
|
||||
* @param adRecords the ad records
|
||||
*/
|
||||
public AdRecordStore(final SparseArray<AdRecord> adRecords) {
|
||||
mAdRecords = adRecords;
|
||||
|
||||
/**
|
||||
* Instantiates a new Bluetooth LE device Ad Record Store.
|
||||
*
|
||||
* @param adRecords the ad records
|
||||
*/
|
||||
public AdRecordStore(final SparseArray<AdRecord> adRecords){
|
||||
mAdRecords = adRecords;
|
||||
mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
|
||||
|
||||
mLocalNameComplete = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_COMPLETE));
|
||||
mLocalNameShort = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_SHORT));
|
||||
|
||||
mLocalNameShort = AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(AdRecord.TYPE_LOCAL_NAME_SHORT));
|
||||
}
|
||||
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#describeContents()
|
||||
*/
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Gets the short local device name.
|
||||
*
|
||||
* @return the local name complete
|
||||
*/
|
||||
public String getLocalNameComplete() {
|
||||
return mLocalNameComplete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the short local device name.
|
||||
*
|
||||
* @return the local name complete
|
||||
*/
|
||||
public String getLocalNameComplete() {
|
||||
return mLocalNameComplete;
|
||||
}
|
||||
/**
|
||||
* Gets the complete local device name.
|
||||
*
|
||||
* @return the local name short
|
||||
*/
|
||||
public String getLocalNameShort() {
|
||||
return mLocalNameShort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the complete local device name.
|
||||
*
|
||||
* @return the local name short
|
||||
*/
|
||||
public String getLocalNameShort() {
|
||||
return mLocalNameShort;
|
||||
}
|
||||
/**
|
||||
* retrieves an individual record.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record
|
||||
*/
|
||||
public AdRecord getRecord(final int record) {
|
||||
return mAdRecords.get(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves an individual record.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record
|
||||
*/
|
||||
public AdRecord getRecord(final int record){
|
||||
return mAdRecords.get(record);
|
||||
}
|
||||
/**
|
||||
* Gets the record data as string.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record data as string
|
||||
*/
|
||||
public String getRecordDataAsString(final int record) {
|
||||
return AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(record));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record data as string.
|
||||
*
|
||||
* @param record the record
|
||||
* @return the record data as string
|
||||
*/
|
||||
public String getRecordDataAsString(final int record){
|
||||
return AdRecordUtils.getRecordDataAsString(
|
||||
mAdRecords.get(record));
|
||||
}
|
||||
/**
|
||||
* Gets the record as collection.
|
||||
*
|
||||
* @return the records as collection
|
||||
*/
|
||||
public Collection<AdRecord> getRecordsAsCollection() {
|
||||
return Collections.unmodifiableCollection(asList(mAdRecords));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the record as collection.
|
||||
*
|
||||
* @return the records as collection
|
||||
*/
|
||||
public Collection<AdRecord> getRecordsAsCollection() {
|
||||
return Collections.unmodifiableCollection(asList(mAdRecords));
|
||||
}
|
||||
/**
|
||||
* Checks if is record present.
|
||||
*
|
||||
* @param record the record
|
||||
* @return true, if is record present
|
||||
*/
|
||||
public boolean isRecordPresent(final int record) {
|
||||
return mAdRecords.indexOfKey(record) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is record present.
|
||||
*
|
||||
* @param record the record
|
||||
* @return true, if is record present
|
||||
*/
|
||||
public boolean isRecordPresent(final int record){
|
||||
return mAdRecords.indexOfKey(record) >= 0;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecordStore [mLocalNameComplete=" + mLocalNameComplete + ", mLocalNameShort=" + mLocalNameShort + "]";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AdRecordStore [mLocalNameComplete=" + mLocalNameComplete + ", mLocalNameShort=" + mLocalNameShort + "]";
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("local_name_complete", mLocalNameComplete);
|
||||
b.putString("local_name_short", mLocalNameShort);
|
||||
b.putSparseParcelableArray("records_array", mAdRecords);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
|
||||
*/
|
||||
@Override
|
||||
public void writeToParcel(final Parcel parcel, final int arg1) {
|
||||
final Bundle b = new Bundle();
|
||||
b.putString("local_name_complete", mLocalNameComplete);
|
||||
b.putString("local_name_short", mLocalNameShort);
|
||||
b.putSparseParcelableArray("records_array", mAdRecords);
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
|
||||
parcel.writeBundle(b);
|
||||
}
|
||||
/**
|
||||
* As list.
|
||||
*
|
||||
* @param <C> the generic type
|
||||
* @param sparseArray the sparse array
|
||||
* @return the collection
|
||||
*/
|
||||
public static <C> Collection<C> asList(final SparseArray<C> sparseArray) {
|
||||
if (sparseArray == null) return null;
|
||||
|
||||
/**
|
||||
* As list.
|
||||
*
|
||||
* @param <C> the generic type
|
||||
* @param sparseArray the sparse array
|
||||
* @return the collection
|
||||
*/
|
||||
public static <C> Collection<C> asList(final SparseArray<C> sparseArray) {
|
||||
if (sparseArray == null) return null;
|
||||
final Collection<C> arrayList = new ArrayList<C>(sparseArray.size());
|
||||
for (int i = 0; i < sparseArray.size(); i++) {
|
||||
arrayList.add(sparseArray.valueAt(i));
|
||||
}
|
||||
|
||||
final Collection<C> arrayList = new ArrayList<C>(sparseArray.size());
|
||||
for (int i = 0; i < sparseArray.size(); i++){
|
||||
arrayList.add(sparseArray.valueAt(i));
|
||||
}
|
||||
|
||||
return arrayList;
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
}
|
||||
|
||||
+92
-85
@@ -8,9 +8,9 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
|
||||
/**
|
||||
* Parses the Manufactured Data field of an iBeacon
|
||||
*
|
||||
* <p/>
|
||||
* The parsing is based on the following schema:
|
||||
*
|
||||
* <p/>
|
||||
* <p>
|
||||
* 0 4C - Byte 1 (LSB) of Company identifier code
|
||||
* 1 00 - Byte 0 (MSB) of Company identifier code (0x004C == Apple)
|
||||
@@ -37,108 +37,115 @@ import uk.co.alt236.bluetoothlelib.util.ByteUtils;
|
||||
* 22 00 - minor
|
||||
* 23 00
|
||||
* 24 c5 - The 2's complement of the calibrated Tx Power
|
||||
*
|
||||
* <p/>
|
||||
* </p>
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*
|
||||
*/
|
||||
|
||||
public final class IBeaconManufacturerData {
|
||||
private final byte[] mData;
|
||||
private final int mCalibratedTxPower;
|
||||
private final int mCompanyIdentidier;
|
||||
private final int mIBeaconAdvertisment;
|
||||
private final int mMajor;
|
||||
private final int mMinor;
|
||||
private final String mUUID;
|
||||
private final byte[] mData;
|
||||
private final int mCalibratedTxPower;
|
||||
private final int mCompanyIdentidier;
|
||||
private final int mIBeaconAdvertisment;
|
||||
private final int mMajor;
|
||||
private final int mMinor;
|
||||
private final String mUUID;
|
||||
|
||||
public IBeaconManufacturerData(final BluetoothLeDevice device){
|
||||
this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData());
|
||||
}
|
||||
public IBeaconManufacturerData(final BluetoothLeDevice device) {
|
||||
this(device.getAdRecordStore().getRecord(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new iBeacon manufacturer data object.
|
||||
/**
|
||||
* Instantiates a new iBeacon manufacturer data object.
|
||||
*
|
||||
* @param data the {@link uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array
|
||||
* @throws IndexOutOfBoundsException if the data array is shorter than expected
|
||||
*/
|
||||
public IBeaconManufacturerData(final byte[] data) {
|
||||
mData = data;
|
||||
|
||||
* @param data the {@link uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord#TYPE_MANUFACTURER_SPECIFIC_DATA} data array
|
||||
* @throws IndexOutOfBoundsException if the data array is shorter than expected
|
||||
*/
|
||||
public IBeaconManufacturerData(final byte[] data){
|
||||
mData = data;
|
||||
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(
|
||||
ByteUtils.invertArray(Arrays.copyOfRange(mData, 0, 2)));
|
||||
|
||||
mCompanyIdentidier = ByteUtils.getIntFrom2ByteArray(
|
||||
ByteUtils.invertArray(Arrays.copyOfRange(mData, 0, 2)));
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4));
|
||||
mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
|
||||
mCalibratedTxPower = data[24];
|
||||
}
|
||||
|
||||
mIBeaconAdvertisment = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 2, 4));
|
||||
mUUID = calculateUUIDString(Arrays.copyOfRange(mData, 4, 20));
|
||||
mMajor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 20, 22));
|
||||
mMinor = ByteUtils.getIntFrom2ByteArray(Arrays.copyOfRange(mData, 22, 24));
|
||||
mCalibratedTxPower = data[24];
|
||||
}
|
||||
/**
|
||||
* Gets the calibrated TX power of the iBeacon device as reported.
|
||||
*
|
||||
* @return the calibrated TX power
|
||||
*/
|
||||
public int getCalibratedTxPower() {
|
||||
return mCalibratedTxPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon company identifier.
|
||||
*
|
||||
* @return the company identifier
|
||||
*/
|
||||
public int getCompanyIdentifier(){
|
||||
return mCompanyIdentidier;
|
||||
}
|
||||
public int getIBeaconAdvertisement() {
|
||||
return mIBeaconAdvertisment;
|
||||
}
|
||||
|
||||
public int getIBeaconAdvertisement(){
|
||||
return mIBeaconAdvertisment;
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon Major value.
|
||||
*
|
||||
* @return the Major value
|
||||
*/
|
||||
public int getMajor() {
|
||||
return mMajor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Minor value.
|
||||
*
|
||||
* @return the Minor value
|
||||
*/
|
||||
public int getMinor(){
|
||||
return mMinor;
|
||||
}
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID() {
|
||||
return mUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the iBeacon UUID.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public String getUUID(){
|
||||
return mUUID;
|
||||
}
|
||||
private static String calculateUUIDString(final byte[] uuid) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
private static String calculateUUIDString(final byte[] uuid){
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < uuid.length; i++) {
|
||||
if (i == 4) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 6) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 8) {
|
||||
sb.append('-');
|
||||
}
|
||||
if (i == 10) {
|
||||
sb.append('-');
|
||||
}
|
||||
|
||||
for(int i = 0 ; i< uuid.length; i++){
|
||||
if(i == 4){sb.append('-');}
|
||||
if(i == 6){sb.append('-');}
|
||||
if(i == 8){sb.append('-');}
|
||||
if(i == 10){sb.append('-');}
|
||||
|
||||
sb.append(
|
||||
Integer.toHexString(ByteUtils.getIntFromByte(uuid[i])));
|
||||
}
|
||||
sb.append(
|
||||
Integer.toHexString(ByteUtils.getIntFromByte(uuid[i])));
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
+106
-106
@@ -4,110 +4,110 @@ import android.bluetooth.BluetoothClass;
|
||||
|
||||
public class BluetoothClassResolver {
|
||||
|
||||
public static String resolveDeviceClass(final int btClass){
|
||||
switch (btClass){
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
|
||||
return "A/V, Camcorder";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
return "A/V, Car Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
return "A/V, Handsfree";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
|
||||
return "A/V, Headphones";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
|
||||
return "A/V, HiFi Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
|
||||
return "A/V, Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE:
|
||||
return "A/V, Microphone";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
|
||||
return "A/V, Portable Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
|
||||
return "A/V, Set Top Box";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED:
|
||||
return "A/V, Uncategorized";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
|
||||
return "A/V, VCR";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA:
|
||||
return "A/V, Video Camera";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING:
|
||||
return "A/V, Video Conferencing";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER:
|
||||
return "A/V, Video Display and Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY:
|
||||
return "A/V, Video Gaming Toy";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR:
|
||||
return "A/V, Video Monitor";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
return "A/V, Video Wearable Headset";
|
||||
case BluetoothClass.Device.COMPUTER_DESKTOP:
|
||||
return "Computer, Desktop";
|
||||
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
|
||||
return "Computer, Handheld PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_LAPTOP:
|
||||
return "Computer, Laptop";
|
||||
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
|
||||
return "Computer, Palm Size PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_SERVER:
|
||||
return "Computer, Server";
|
||||
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
|
||||
return "Computer, Uncategorized";
|
||||
case BluetoothClass.Device.COMPUTER_WEARABLE:
|
||||
return "Computer, Wearable";
|
||||
case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE:
|
||||
return "Health, Blood Pressure";
|
||||
case BluetoothClass.Device.HEALTH_DATA_DISPLAY:
|
||||
return "Health, Data Display";
|
||||
case BluetoothClass.Device.HEALTH_GLUCOSE:
|
||||
return "Health, Glucose";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER :
|
||||
return "Health, Pulse Oximeter";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_RATE :
|
||||
return "Health, Pulse Rate";
|
||||
case BluetoothClass.Device.HEALTH_THERMOMETER :
|
||||
return "Health, Thermometer";
|
||||
case BluetoothClass.Device.HEALTH_UNCATEGORIZED :
|
||||
return "Health, Uncategorized";
|
||||
case BluetoothClass.Device.HEALTH_WEIGHING:
|
||||
return "Health, Weighting";
|
||||
case BluetoothClass.Device.PHONE_CELLULAR:
|
||||
return "Phone, Cellular";
|
||||
case BluetoothClass.Device.PHONE_CORDLESS:
|
||||
return "Phone, Cordless";
|
||||
case BluetoothClass.Device.PHONE_ISDN:
|
||||
return "Phone, ISDN";
|
||||
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
|
||||
return "Phone, Modem or Gateway";
|
||||
case BluetoothClass.Device.PHONE_SMART:
|
||||
return "Phone, Smart";
|
||||
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
|
||||
return "Phone, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_CONTROLLER:
|
||||
return "Toy, Controller";
|
||||
case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE:
|
||||
return "Toy, Doll/Action Figure";
|
||||
case BluetoothClass.Device.TOY_GAME:
|
||||
return "Toy, Game";
|
||||
case BluetoothClass.Device.TOY_ROBOT:
|
||||
return "Toy, Robot";
|
||||
case BluetoothClass.Device.TOY_UNCATEGORIZED:
|
||||
return "Toy, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_VEHICLE:
|
||||
return "Toy, Vehicle";
|
||||
case BluetoothClass.Device.WEARABLE_GLASSES:
|
||||
return "Wearable, Glasses";
|
||||
case BluetoothClass.Device.WEARABLE_HELMET:
|
||||
return "Wearable, Helmet";
|
||||
case BluetoothClass.Device.WEARABLE_JACKET:
|
||||
return "Wearable, Jacket";
|
||||
case BluetoothClass.Device.WEARABLE_PAGER:
|
||||
return "Wearable, Pager";
|
||||
case BluetoothClass.Device.WEARABLE_UNCATEGORIZED:
|
||||
return "Wearable, Uncategorized";
|
||||
case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
|
||||
return "Wearable, Wrist Watch";
|
||||
default:
|
||||
return "Unknown, Unknown (class=" + btClass +")";
|
||||
}
|
||||
}
|
||||
public static String resolveDeviceClass(final int btClass) {
|
||||
switch (btClass) {
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAMCORDER:
|
||||
return "A/V, Camcorder";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
|
||||
return "A/V, Car Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
|
||||
return "A/V, Handsfree";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
|
||||
return "A/V, Headphones";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
|
||||
return "A/V, HiFi Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
|
||||
return "A/V, Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_MICROPHONE:
|
||||
return "A/V, Microphone";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_PORTABLE_AUDIO:
|
||||
return "A/V, Portable Audio";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX:
|
||||
return "A/V, Set Top Box";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_UNCATEGORIZED:
|
||||
return "A/V, Uncategorized";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VCR:
|
||||
return "A/V, VCR";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CAMERA:
|
||||
return "A/V, Video Camera";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_CONFERENCING:
|
||||
return "A/V, Video Conferencing";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER:
|
||||
return "A/V, Video Display and Loudspeaker";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_GAMING_TOY:
|
||||
return "A/V, Video Gaming Toy";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_VIDEO_MONITOR:
|
||||
return "A/V, Video Monitor";
|
||||
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
|
||||
return "A/V, Video Wearable Headset";
|
||||
case BluetoothClass.Device.COMPUTER_DESKTOP:
|
||||
return "Computer, Desktop";
|
||||
case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA:
|
||||
return "Computer, Handheld PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_LAPTOP:
|
||||
return "Computer, Laptop";
|
||||
case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA:
|
||||
return "Computer, Palm Size PC/PDA";
|
||||
case BluetoothClass.Device.COMPUTER_SERVER:
|
||||
return "Computer, Server";
|
||||
case BluetoothClass.Device.COMPUTER_UNCATEGORIZED:
|
||||
return "Computer, Uncategorized";
|
||||
case BluetoothClass.Device.COMPUTER_WEARABLE:
|
||||
return "Computer, Wearable";
|
||||
case BluetoothClass.Device.HEALTH_BLOOD_PRESSURE:
|
||||
return "Health, Blood Pressure";
|
||||
case BluetoothClass.Device.HEALTH_DATA_DISPLAY:
|
||||
return "Health, Data Display";
|
||||
case BluetoothClass.Device.HEALTH_GLUCOSE:
|
||||
return "Health, Glucose";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_OXIMETER:
|
||||
return "Health, Pulse Oximeter";
|
||||
case BluetoothClass.Device.HEALTH_PULSE_RATE:
|
||||
return "Health, Pulse Rate";
|
||||
case BluetoothClass.Device.HEALTH_THERMOMETER:
|
||||
return "Health, Thermometer";
|
||||
case BluetoothClass.Device.HEALTH_UNCATEGORIZED:
|
||||
return "Health, Uncategorized";
|
||||
case BluetoothClass.Device.HEALTH_WEIGHING:
|
||||
return "Health, Weighting";
|
||||
case BluetoothClass.Device.PHONE_CELLULAR:
|
||||
return "Phone, Cellular";
|
||||
case BluetoothClass.Device.PHONE_CORDLESS:
|
||||
return "Phone, Cordless";
|
||||
case BluetoothClass.Device.PHONE_ISDN:
|
||||
return "Phone, ISDN";
|
||||
case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY:
|
||||
return "Phone, Modem or Gateway";
|
||||
case BluetoothClass.Device.PHONE_SMART:
|
||||
return "Phone, Smart";
|
||||
case BluetoothClass.Device.PHONE_UNCATEGORIZED:
|
||||
return "Phone, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_CONTROLLER:
|
||||
return "Toy, Controller";
|
||||
case BluetoothClass.Device.TOY_DOLL_ACTION_FIGURE:
|
||||
return "Toy, Doll/Action Figure";
|
||||
case BluetoothClass.Device.TOY_GAME:
|
||||
return "Toy, Game";
|
||||
case BluetoothClass.Device.TOY_ROBOT:
|
||||
return "Toy, Robot";
|
||||
case BluetoothClass.Device.TOY_UNCATEGORIZED:
|
||||
return "Toy, Uncategorized";
|
||||
case BluetoothClass.Device.TOY_VEHICLE:
|
||||
return "Toy, Vehicle";
|
||||
case BluetoothClass.Device.WEARABLE_GLASSES:
|
||||
return "Wearable, Glasses";
|
||||
case BluetoothClass.Device.WEARABLE_HELMET:
|
||||
return "Wearable, Helmet";
|
||||
case BluetoothClass.Device.WEARABLE_JACKET:
|
||||
return "Wearable, Jacket";
|
||||
case BluetoothClass.Device.WEARABLE_PAGER:
|
||||
return "Wearable, Pager";
|
||||
case BluetoothClass.Device.WEARABLE_UNCATEGORIZED:
|
||||
return "Wearable, Uncategorized";
|
||||
case BluetoothClass.Device.WEARABLE_WRIST_WATCH:
|
||||
return "Wearable, Wrist Watch";
|
||||
default:
|
||||
return "Unknown, Unknown (class=" + btClass + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+633
-633
File diff suppressed because it is too large
Load Diff
+360
-364
@@ -5,382 +5,378 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* The UUIDS have been collected from the following sources:
|
||||
*
|
||||
* <p/>
|
||||
* - http://developer.nokia.com/community/wiki/Bluetooth_Services_for_Windows_Phone
|
||||
* - The Bluez project
|
||||
*
|
||||
* @author Alexandros Schillings
|
||||
*
|
||||
*/
|
||||
public class GattAttributeResolver {
|
||||
public static final String BASE_GUID = "00000001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_PROTOCOL_SDP = "00000002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String USER_DATAGRAM_PROTOCOL_UDP = "00000003-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM = "00000004-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCP = "00000005-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSBIN = "00000006-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSAT = "00000008-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBJECT_EXCHANGE_PROTOCOL_OBEX = "00000009-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IP = "0000000a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FTP = "0000000c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HTTP = "0000000e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WSP = "0000000f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BNEP_SVC = "00000010-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_PROTOCOL = "00000011-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HIDP = "00000012-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CONTROL_CHANNEL_PROTOCOL = "00000014-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_DATA_CHANNEL_PROTOCOL = "00000016-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_NOTIFICATION_PROTOCOL = "00000017-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VCTP_PROTOCOL = "00000019-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VDTP_PROTOCOL = "0000001b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CMPT_PROTOCOL = "0000001d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDI_C_PLANE_PROTOCOL = "0000001e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_CONTROL_CHANNEL = "0000001f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_DATA_CHANNEL = "00000100-0000-1000-8000-00805f9b34fb";
|
||||
public static final String L2CAP = "00001000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_SERVER = "00001001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BROWSE_GROUP_DESCRIPTOR = "00001002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PUBLIC_BROWSE_GROUP = "00001101-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SPP = "00001102-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LAN_ACCESS_USING_PPP = "00001103-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DUN_GW = "00001104-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_SYNC = "00001105-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_OBJECT_PUSH = "00001106-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_FILE_TRANSFER = "00001107-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IRMC_SYNC_COMMAND = "00001108-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HSP_HS = "00001109-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CORDLESS_TELEPHONY = "0000110a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SOURCE = "0000110b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SINK = "0000110c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AV_REMOTE_CONTROL_TARGET = "0000110d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ADVANCED_AUDIO = "0000110e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AVRCP_REMOTE = "0000110f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING = "00001110-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERCOM = "00001111-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FAX = "00001112-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEADSET_PROFILE_HSP_AUDIO_GATEWAY = "00001113-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP = "00001114-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP_CLIENT = "00001115-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PANU = "00001116-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NAP = "00001117-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GN = "00001118-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING = "00001119-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_PRINTING = "0000111a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING = "0000111b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_RESPONDER = "0000111c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_AUTOMATIC_ARCHIVE = "0000111d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_REFERENCE_OBJECTS = "0000111e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP = "0000111f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY = "00001120-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING_REFERENCE_OBJECTS = "00001121-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFLECTED_UI = "00001122-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BASIC_PRINTING = "00001123-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PRINTING_STATUS = "00001124-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HID = "00001125-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CABLE_REPLACEMENT = "00001126-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_PRINT = "00001127-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_SCAN = "00001128-0000-1000-8000-00805f9b34fb";
|
||||
public static final String COMMON_ISDN_ACCESS = "00001129-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING_GATEWAY = "0000112a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDIMT = "0000112b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDITA = "0000112c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_VIDEO = "0000112d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SIM_ACCESS = "0000112e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PCE = "0000112f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PSE = "00001130-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PBAP = "00001132-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAS = "00001133-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MNS = "00001134-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAP = "00001200-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNP = "00001201-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_NETWORKING = "00001202-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_FILE_TRANSFER = "00001203-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_AUDIO = "00001204-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_TELEPHONY = "00001205-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP = "00001206-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_IP = "00001300-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_PAN = "00001301-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_LAP = "00001302-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_L2CAP = "00001303-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE = "00001304-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SINK = "00001305-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP = "00001400-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP = "00001401-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SOURCE = "00001402-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SINK = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GAP = "00001801-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GATT = "00001802-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMMEDIATE_ALERT = "00001803-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LINK_LOSS = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER = "00001809-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_THERMOMETER = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_INFORMATION = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE = "00001816-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CYCLING_SC = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_NAME = "00002a01-0000-1000-8000-00805f9b34fb";
|
||||
public static final String APPEARANCE = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PRIVACY_FLAG = "00002a03-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RECONNECTION_ADDRESS = "00002a04-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = "00002a05-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_CHANGED = "00002a06-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_LEVEL = "00002a07-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER_LEVEL = "00002a08-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DATE_TIME = "00002a09-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_OF_WEEK = "00002a0a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_DATE_TIME = "00002a0c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String EXACT_TIME_256 = "00002a0d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DST_OFFSET = "00002a0e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ZONE = "00002a0f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LOCAL_TIME_INFORMATION = "00002a11-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_WITH_DST = "00002a12-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ACCURACY = "00002a13-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_SOURCE = "00002a14-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_TIME_INFORMATION = "00002a16-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_CONTROL_POINT = "00002a17-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_STATE = "00002a1c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_MEASUREMENT = "00002a1d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_TYPE = "00002a1e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_TEMPERATURE = "00002a21-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MEASUREMENT_INTERVAL = "00002a23-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SYSTEM_ID = "00002a24-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MODEL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERIAL_NUMBER_STRING = "00002a26-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FIRMWARE_REVISION_STRING = "00002a27-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDWARE_REVISION_STRING = "00002a28-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SOFTWARE_REVISION_STRING = "00002a29-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MANUFACTURER_NAME_STRING = "00002a2a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IEEE_1107320601_REGULATORY = "00002a2b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CURRENT_TIME = "00002a35-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_MEASUREMENT = "00002a36-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_CUFF_PRESSURE = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_MEASUREMENT = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BODY_SENSOR_LOCATION = "00002a39-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_CONTROL_POINT = "00002a3f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_STATUS = "00002a40-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_CONTROL_POINT = "00002a41-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_SETTING = "00002a42-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID_BIT_MASK = "00002a43-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID = "00002a44-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_NOTIFICATION_CONTROL_POINT = "00002a45-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UNREAD_ALERT_STATUS = "00002a46-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NEW_ALERT = "00002a47-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_NEW_ALERT_CATEGORY = "00002a48-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_UNREAD_ALERT_CATEGORY = "00002a49-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_FEATURE = "00002a50-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNPID = "00002a55-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SC_CONTROL_POINT = "00002a5b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_MEASUREMENT = "00002a5c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_FEATURE = "00002a5d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SENSOR_LOCATION = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ACTIVESYNC = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ESTIMOTE_SERVICE = "b9403000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_UUID = "b9403003-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MAJOR = "b9403001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MINOR = "b9403002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_BATTERY = "b9403041-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_TEMPERATURE = "b9403021-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_POWER = "b9403011-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_INTERVAL = "b9403012-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_VERSION_SERVICE = "b9404000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_SOFTWARE_VERSION = "b9404001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_HARDWARE_VERSION = "b9404002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_AUTHENTICATION_SERVICE = "b9402000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_SEED = "b9402001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String BASE_GUID = "00000001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_PROTOCOL_SDP = "00000002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String USER_DATAGRAM_PROTOCOL_UDP = "00000003-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM = "00000004-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCP = "00000005-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSBIN = "00000006-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TCSAT = "00000008-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBJECT_EXCHANGE_PROTOCOL_OBEX = "00000009-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IP = "0000000a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FTP = "0000000c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HTTP = "0000000e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WSP = "0000000f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BNEP_SVC = "00000010-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_PROTOCOL = "00000011-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HIDP = "00000012-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CONTROL_CHANNEL_PROTOCOL = "00000014-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_DATA_CHANNEL_PROTOCOL = "00000016-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_NOTIFICATION_PROTOCOL = "00000017-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VCTP_PROTOCOL = "00000019-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VDTP_PROTOCOL = "0000001b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CMPT_PROTOCOL = "0000001d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDI_C_PLANE_PROTOCOL = "0000001e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_CONTROL_CHANNEL = "0000001f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MCAP_DATA_CHANNEL = "00000100-0000-1000-8000-00805f9b34fb";
|
||||
public static final String L2CAP = "00001000-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_DISCOVERY_SERVER = "00001001-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BROWSE_GROUP_DESCRIPTOR = "00001002-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PUBLIC_BROWSE_GROUP = "00001101-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SPP = "00001102-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LAN_ACCESS_USING_PPP = "00001103-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DUN_GW = "00001104-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_SYNC = "00001105-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_OBJECT_PUSH = "00001106-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_FILE_TRANSFER = "00001107-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IRMC_SYNC_COMMAND = "00001108-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HSP_HS = "00001109-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CORDLESS_TELEPHONY = "0000110a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SOURCE = "0000110b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_SINK = "0000110c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AV_REMOTE_CONTROL_TARGET = "0000110d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ADVANCED_AUDIO = "0000110e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AVRCP_REMOTE = "0000110f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING = "00001110-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERCOM = "00001111-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FAX = "00001112-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEADSET_PROFILE_HSP_AUDIO_GATEWAY = "00001113-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP = "00001114-0000-1000-8000-00805f9b34fb";
|
||||
public static final String WAP_CLIENT = "00001115-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PANU = "00001116-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NAP = "00001117-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GN = "00001118-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING = "00001119-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_PRINTING = "0000111a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING = "0000111b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_RESPONDER = "0000111c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_AUTOMATIC_ARCHIVE = "0000111d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMAGING_REFERENCE_OBJECTS = "0000111e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP = "0000111f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY = "00001120-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DIRECT_PRINTING_REFERENCE_OBJECTS = "00001121-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFLECTED_UI = "00001122-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BASIC_PRINTING = "00001123-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PRINTING_STATUS = "00001124-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HID = "00001125-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDCOPY_CABLE_REPLACEMENT = "00001126-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_PRINT = "00001127-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HCR_SCAN = "00001128-0000-1000-8000-00805f9b34fb";
|
||||
public static final String COMMON_ISDN_ACCESS = "00001129-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_CONFERENCING_GATEWAY = "0000112a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDIMT = "0000112b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UDITA = "0000112c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String AUDIO_VIDEO = "0000112d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SIM_ACCESS = "0000112e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PCE = "0000112f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PSE = "00001130-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_PBAP = "00001132-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAS = "00001133-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MNS = "00001134-0000-1000-8000-00805f9b34fb";
|
||||
public static final String OBEX_MAP = "00001200-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNP = "00001201-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_NETWORKING = "00001202-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_FILE_TRANSFER = "00001203-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_AUDIO = "00001204-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GENERIC_TELEPHONY = "00001205-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP = "00001206-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UPNP_IP = "00001300-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_PAN = "00001301-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_IP_LAP = "00001302-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ESDP_UPNP_L2CAP = "00001303-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE = "00001304-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP_SINK = "00001305-0000-1000-8000-00805f9b34fb";
|
||||
public static final String VIDEO_DISTRIBUTION_PROFILE_VDP = "00001400-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP = "00001401-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SOURCE = "00001402-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_DEVICE_PROFILE_HDP_SINK = "00001800-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GAP = "00001801-0000-1000-8000-00805f9b34fb";
|
||||
public static final String GATT = "00001802-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IMMEDIATE_ALERT = "00001803-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LINK_LOSS = "00001804-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER = "00001809-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEALTH_THERMOMETER = "0000180a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_INFORMATION = "0000180d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE = "00001816-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CYCLING_SC = "00002902-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CLIENT_CHARACTERISTIC_CONFIG = "00002a00-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DEVICE_NAME = "00002a01-0000-1000-8000-00805f9b34fb";
|
||||
public static final String APPEARANCE = "00002a02-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PRIVACY_FLAG = "00002a03-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RECONNECTION_ADDRESS = "00002a04-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS = "00002a05-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERVICE_CHANGED = "00002a06-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_LEVEL = "00002a07-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TX_POWER_LEVEL = "00002a08-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DATE_TIME = "00002a09-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_OF_WEEK = "00002a0a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DAY_DATE_TIME = "00002a0c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String EXACT_TIME_256 = "00002a0d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String DST_OFFSET = "00002a0e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ZONE = "00002a0f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String LOCAL_TIME_INFORMATION = "00002a11-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_WITH_DST = "00002a12-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_ACCURACY = "00002a13-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_SOURCE = "00002a14-0000-1000-8000-00805f9b34fb";
|
||||
public static final String REFERENCE_TIME_INFORMATION = "00002a16-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_CONTROL_POINT = "00002a17-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TIME_UPDATE_STATE = "00002a1c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_MEASUREMENT = "00002a1d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String TEMPERATURE_TYPE = "00002a1e-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_TEMPERATURE = "00002a21-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MEASUREMENT_INTERVAL = "00002a23-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SYSTEM_ID = "00002a24-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MODEL_NUMBER_STRING = "00002a25-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SERIAL_NUMBER_STRING = "00002a26-0000-1000-8000-00805f9b34fb";
|
||||
public static final String FIRMWARE_REVISION_STRING = "00002a27-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HARDWARE_REVISION_STRING = "00002a28-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SOFTWARE_REVISION_STRING = "00002a29-0000-1000-8000-00805f9b34fb";
|
||||
public static final String MANUFACTURER_NAME_STRING = "00002a2a-0000-1000-8000-00805f9b34fb";
|
||||
public static final String IEEE_1107320601_REGULATORY = "00002a2b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CURRENT_TIME = "00002a35-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_MEASUREMENT = "00002a36-0000-1000-8000-00805f9b34fb";
|
||||
public static final String INTERMEDIATE_CUFF_PRESSURE = "00002a37-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_MEASUREMENT = "00002a38-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BODY_SENSOR_LOCATION = "00002a39-0000-1000-8000-00805f9b34fb";
|
||||
public static final String HEART_RATE_CONTROL_POINT = "00002a3f-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_STATUS = "00002a40-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_CONTROL_POINT = "00002a41-0000-1000-8000-00805f9b34fb";
|
||||
public static final String RINGER_SETTING = "00002a42-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID_BIT_MASK = "00002a43-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_CATEGORY_ID = "00002a44-0000-1000-8000-00805f9b34fb";
|
||||
public static final String ALERT_NOTIFICATION_CONTROL_POINT = "00002a45-0000-1000-8000-00805f9b34fb";
|
||||
public static final String UNREAD_ALERT_STATUS = "00002a46-0000-1000-8000-00805f9b34fb";
|
||||
public static final String NEW_ALERT = "00002a47-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_NEW_ALERT_CATEGORY = "00002a48-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SUPPORTED_UNREAD_ALERT_CATEGORY = "00002a49-0000-1000-8000-00805f9b34fb";
|
||||
public static final String BLOOD_PRESSURE_FEATURE = "00002a50-0000-1000-8000-00805f9b34fb";
|
||||
public static final String PNPID = "00002a55-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SC_CONTROL_POINT = "00002a5b-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_MEASUREMENT = "00002a5c-0000-1000-8000-00805f9b34fb";
|
||||
public static final String CSC_FEATURE = "00002a5d-0000-1000-8000-00805f9b34fb";
|
||||
public static final String SENSOR_LOCATION = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ACTIVESYNC = "831c4071-7bc8-4a9c-a01c-15df25a4adbc";
|
||||
public static final String ESTIMOTE_SERVICE = "b9403000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_UUID = "b9403003-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MAJOR = "b9403001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_MINOR = "b9403002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_BATTERY = "b9403041-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_TEMPERATURE = "b9403021-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_POWER = "b9403011-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_INTERVAL = "b9403012-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_VERSION_SERVICE = "b9404000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_SOFTWARE_VERSION = "b9404001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_HARDWARE_VERSION = "b9404002-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_AUTHENTICATION_SERVICE = "b9402000-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_SEED = "b9402001-f5f8-466e-aff9-25556b57fe6d";
|
||||
public static final String ESTIMOTE_ADVERTISING_VECTOR = "b9402002-f5f8-466e-aff9-25556b57fe6d";
|
||||
|
||||
|
||||
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
|
||||
|
||||
private final static Map<String, String> sGattAttributesMap = populateGattAttributesMap();
|
||||
public static String getAttributeName(final String uuid, final String fallback) {
|
||||
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
|
||||
public static String getAttributeName(final String uuid, final String fallback){
|
||||
final String name = sGattAttributesMap.get(uuid.toLowerCase(Locale.US));
|
||||
return name == null ? fallback : name;
|
||||
}
|
||||
private static Map<String, String> populateGattAttributesMap() {
|
||||
final Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
private static Map<String, String> populateGattAttributesMap() {
|
||||
final Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
map.put(BASE_GUID , "Service Discovery Protocol (SDP)");
|
||||
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP , "User Datagram Protocol (UDP)");
|
||||
map.put(USER_DATAGRAM_PROTOCOL_UDP , "Radio Frequency Communication Protocol (RFCOMM)");
|
||||
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM , "TCP");
|
||||
map.put(TCP , "TCSBIN");
|
||||
map.put(TCSBIN , "TCSAT");
|
||||
map.put(TCSAT , "Object Exchange Protocol (OBEX)");
|
||||
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX , "IP");
|
||||
map.put(IP , "FTP");
|
||||
map.put(FTP , "HTTP");
|
||||
map.put(HTTP , "WSP");
|
||||
map.put(WSP , "BNEP_SVC");
|
||||
map.put(BNEP_SVC , "UPNP Protocol");
|
||||
map.put(UPNP_PROTOCOL , "HIDP");
|
||||
map.put(HIDP , "Hardcopy Control Channel Protocol");
|
||||
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL , "Hardcopy Data Channel Protocol");
|
||||
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL , "Hardcopy Notification Protocol");
|
||||
map.put(HARDCOPY_NOTIFICATION_PROTOCOL , "VCTP Protocol");
|
||||
map.put(VCTP_PROTOCOL , "VDTP Protocol");
|
||||
map.put(VDTP_PROTOCOL , "CMPT Protocol");
|
||||
map.put(CMPT_PROTOCOL , "UDI C Plane Protocol");
|
||||
map.put(UDI_C_PLANE_PROTOCOL , "MCAP Control Channel");
|
||||
map.put(MCAP_CONTROL_CHANNEL , "MCAP Data Channel");
|
||||
map.put(MCAP_DATA_CHANNEL , "L2CAP");
|
||||
map.put(L2CAP , "Service Discovery Server");
|
||||
map.put(SERVICE_DISCOVERY_SERVER , "Browse Group Descriptor");
|
||||
map.put(BROWSE_GROUP_DESCRIPTOR , "Public Browse Group");
|
||||
map.put(PUBLIC_BROWSE_GROUP , "SPP");
|
||||
map.put(SPP , "LAN Access Using PPP");
|
||||
map.put(LAN_ACCESS_USING_PPP , "DUN_GW");
|
||||
map.put(DUN_GW , "OBEX_SYNC");
|
||||
map.put(OBEX_SYNC , "OBEX Object Push");
|
||||
map.put(OBEX_OBJECT_PUSH , "OBEX File Transfer");
|
||||
map.put(OBEX_FILE_TRANSFER , "IrMC Sync Command");
|
||||
map.put(IRMC_SYNC_COMMAND , "HSP_HS");
|
||||
map.put(HSP_HS , "Cordless Telephony");
|
||||
map.put(CORDLESS_TELEPHONY , "Audio Source");
|
||||
map.put(AUDIO_SOURCE , "Audio Sink");
|
||||
map.put(AUDIO_SINK , "AV Remote Control Target");
|
||||
map.put(AV_REMOTE_CONTROL_TARGET , "ADVANCED_AUDIO");
|
||||
map.put(ADVANCED_AUDIO , "AVRCP_REMOTE");
|
||||
map.put(AVRCP_REMOTE , "Video Conferencing");
|
||||
map.put(VIDEO_CONFERENCING , "Intercom");
|
||||
map.put(INTERCOM , "FAX");
|
||||
map.put(FAX , "Headset Profile (HSP) - Audio Gateway");
|
||||
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY , "WAP");
|
||||
map.put(WAP , "WAP Client");
|
||||
map.put(WAP_CLIENT , "PANU");
|
||||
map.put(PANU , "NAP");
|
||||
map.put(NAP , "GN");
|
||||
map.put(GN , "Direct Printing");
|
||||
map.put(DIRECT_PRINTING , "Reference Printing");
|
||||
map.put(REFERENCE_PRINTING , "Imaging");
|
||||
map.put(IMAGING , "Imaging Responder");
|
||||
map.put(IMAGING_RESPONDER , "Imaging Automatic Archive");
|
||||
map.put(IMAGING_AUTOMATIC_ARCHIVE , "Imaging Reference Objects");
|
||||
map.put(IMAGING_REFERENCE_OBJECTS , "Hands Free Profile (HFP)");
|
||||
map.put(HANDS_FREE_PROFILE_HFP , "Hands Free Profile (HFP) – Audio Gateway");
|
||||
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY , "Direct Printing Reference Objects");
|
||||
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS , "Reflected UI");
|
||||
map.put(REFLECTED_UI , "Basic Printing");
|
||||
map.put(BASIC_PRINTING , "Printing Status");
|
||||
map.put(PRINTING_STATUS , "HID");
|
||||
map.put(HID , "Hardcopy Cable Replacement");
|
||||
map.put(HARDCOPY_CABLE_REPLACEMENT , "HCR Print");
|
||||
map.put(HCR_PRINT , "HCR Scan");
|
||||
map.put(HCR_SCAN , "Common ISDN Access");
|
||||
map.put(COMMON_ISDN_ACCESS , "Video Conferencing Gateway");
|
||||
map.put(VIDEO_CONFERENCING_GATEWAY , "UDIMT");
|
||||
map.put(UDIMT , "UDITA");
|
||||
map.put(UDITA , "Audio Video");
|
||||
map.put(AUDIO_VIDEO , "SIM Access");
|
||||
map.put(SIM_ACCESS , "OBEX PCE");
|
||||
map.put(OBEX_PCE , "OBEX PSE");
|
||||
map.put(OBEX_PSE , "OBEX PBAP");
|
||||
map.put(OBEX_PBAP , "OBEX MAS");
|
||||
map.put(OBEX_MAS , "OBEX MNS");
|
||||
map.put(OBEX_MNS , "OBEX MAP");
|
||||
map.put(OBEX_MAP , "PNP");
|
||||
map.put(PNP , "Generic Networking");
|
||||
map.put(GENERIC_NETWORKING , "Generic File Transfer");
|
||||
map.put(GENERIC_FILE_TRANSFER , "Generic Audio");
|
||||
map.put(GENERIC_AUDIO , "Generic Telephony");
|
||||
map.put(GENERIC_TELEPHONY , "UPNP");
|
||||
map.put(UPNP , "UPNP IP");
|
||||
map.put(UPNP_IP , "ESDP UPnP IP PAN");
|
||||
map.put(ESDP_UPNP_IP_PAN , "ESDP UPnP IP LAP");
|
||||
map.put(ESDP_UPNP_IP_LAP , "ESDP Upnp L2CAP");
|
||||
map.put(ESDP_UPNP_L2CAP , "Video Distribution Profile (VDP) - Source");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE , "Video Distribution Profile (VDP) - Sink");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK , "Video Distribution Profile (VDP)");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP , "Health Device Profile (HDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP , "Health Device Profile (HDP) - Source");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE , "Health Device Profile (HDP) - Sink");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK , "GAP");
|
||||
map.put(GAP , "GATT");
|
||||
map.put(GATT , "IMMEDIATE_ALERT");
|
||||
map.put(IMMEDIATE_ALERT , "LINK_LOSS");
|
||||
map.put(LINK_LOSS , "TX_POWER");
|
||||
map.put(TX_POWER , "Health Thermometer");
|
||||
map.put(HEALTH_THERMOMETER , "Device Information");
|
||||
map.put(DEVICE_INFORMATION , "HEART_RATE");
|
||||
map.put(HEART_RATE , "CYCLING_SC");
|
||||
map.put(CYCLING_SC , "CLIENT_CHARACTERISTIC_CONFIG");
|
||||
map.put(CLIENT_CHARACTERISTIC_CONFIG , "Device Name");
|
||||
map.put(DEVICE_NAME , "Appearance");
|
||||
map.put(APPEARANCE , "Peripheral Privacy Flag");
|
||||
map.put(PERIPHERAL_PRIVACY_FLAG , "Reconnection Address");
|
||||
map.put(RECONNECTION_ADDRESS , "Peripheral Preferred Connection Parameters");
|
||||
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS , "Service Changed");
|
||||
map.put(SERVICE_CHANGED , "Alert Level");
|
||||
map.put(ALERT_LEVEL , "Tx Power Level");
|
||||
map.put(TX_POWER_LEVEL , "Date Time");
|
||||
map.put(DATE_TIME , "Day of Week");
|
||||
map.put(DAY_OF_WEEK , "Day Date Time");
|
||||
map.put(DAY_DATE_TIME , "Exact Time 256");
|
||||
map.put(EXACT_TIME_256 , "DST Offset");
|
||||
map.put(DST_OFFSET , "Time Zone");
|
||||
map.put(TIME_ZONE , "Local Time Information");
|
||||
map.put(LOCAL_TIME_INFORMATION , "Time with DST");
|
||||
map.put(TIME_WITH_DST , "Time Accuracy");
|
||||
map.put(TIME_ACCURACY , "Time Source");
|
||||
map.put(TIME_SOURCE , "Reference Time Information");
|
||||
map.put(REFERENCE_TIME_INFORMATION , "Time Update Control Point");
|
||||
map.put(TIME_UPDATE_CONTROL_POINT , "Time Update State");
|
||||
map.put(TIME_UPDATE_STATE , "Temperature Measurement");
|
||||
map.put(TEMPERATURE_MEASUREMENT , "Temperature Type");
|
||||
map.put(TEMPERATURE_TYPE , "Intermediate Temperature");
|
||||
map.put(INTERMEDIATE_TEMPERATURE , "Measurement Interval");
|
||||
map.put(MEASUREMENT_INTERVAL , "System ID");
|
||||
map.put(SYSTEM_ID , "Model Number String");
|
||||
map.put(MODEL_NUMBER_STRING , "Serial Number String");
|
||||
map.put(SERIAL_NUMBER_STRING , "Firmware Revision String");
|
||||
map.put(FIRMWARE_REVISION_STRING , "Hardware Revision String");
|
||||
map.put(HARDWARE_REVISION_STRING , "Software Revision String");
|
||||
map.put(SOFTWARE_REVISION_STRING , "Manufacturer Name String");
|
||||
map.put(MANUFACTURER_NAME_STRING , "IEEE 11073-20601 Regulatory");
|
||||
map.put(IEEE_1107320601_REGULATORY , "Current Time");
|
||||
map.put(CURRENT_TIME , "Blood Pressure Measurement");
|
||||
map.put(BLOOD_PRESSURE_MEASUREMENT , "Intermediate Cuff Pressure");
|
||||
map.put(INTERMEDIATE_CUFF_PRESSURE , "Heart Rate Measurement");
|
||||
map.put(HEART_RATE_MEASUREMENT , "Body Sensor Location");
|
||||
map.put(BODY_SENSOR_LOCATION , "Heart Rate Control Point");
|
||||
map.put(HEART_RATE_CONTROL_POINT , "Alert Status");
|
||||
map.put(ALERT_STATUS , "Ringer Control Point");
|
||||
map.put(RINGER_CONTROL_POINT , "Ringer Setting");
|
||||
map.put(RINGER_SETTING , "Alert Category ID Bit Mask");
|
||||
map.put(ALERT_CATEGORY_ID_BIT_MASK , "Alert Category ID");
|
||||
map.put(ALERT_CATEGORY_ID , "Alert Notification Control Point");
|
||||
map.put(ALERT_NOTIFICATION_CONTROL_POINT , "Unread Alert Status");
|
||||
map.put(UNREAD_ALERT_STATUS , "New Alert");
|
||||
map.put(NEW_ALERT , "Supported New Alert Category");
|
||||
map.put(SUPPORTED_NEW_ALERT_CATEGORY , "Supported Unread Alert Category");
|
||||
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY , "Blood Pressure Feature");
|
||||
map.put(BLOOD_PRESSURE_FEATURE , "PNPID");
|
||||
map.put(PNPID , "SC_CONTROL_POINT");
|
||||
map.put(SC_CONTROL_POINT , "CSC_MEASUREMENT");
|
||||
map.put(CSC_MEASUREMENT , "CSC_FEATURE");
|
||||
map.put(CSC_FEATURE , "SENSOR_LOCATION");
|
||||
map.put(SENSOR_LOCATION , "ActiveSync");
|
||||
map.put(ACTIVESYNC , "ActiveSync");
|
||||
map.put(ESTIMOTE_SERVICE , "Estimote Service");
|
||||
map.put(ESTIMOTE_UUID , "Estimote UUID");
|
||||
map.put(ESTIMOTE_MAJOR , "Estimote Major");
|
||||
map.put(ESTIMOTE_MINOR , "Estimote Minor");
|
||||
map.put(ESTIMOTE_BATTERY , "Estimote Battery");
|
||||
map.put(ESTIMOTE_TEMPERATURE , "Estimote Temperature");
|
||||
map.put(ESTIMOTE_POWER , "Estimote Power");
|
||||
map.put(ESTIMOTE_ADVERTISING_INTERVAL , "Estimote Advertising Interval");
|
||||
map.put(ESTIMOTE_VERSION_SERVICE , "Estimote Version Service");
|
||||
map.put(ESTIMOTE_SOFTWARE_VERSION , "Estimote Software Version");
|
||||
map.put(ESTIMOTE_HARDWARE_VERSION , "Estimote Hardware Version");
|
||||
map.put(ESTIMOTE_AUTHENTICATION_SERVICE , "Estimote Authentication Service");
|
||||
map.put(ESTIMOTE_ADVERTISING_SEED , "Estimote Advertising Seed");
|
||||
map.put(ESTIMOTE_ADVERTISING_VECTOR , "Estimote Advertising Vector");
|
||||
map.put(BASE_GUID, "Service Discovery Protocol (SDP)");
|
||||
map.put(SERVICE_DISCOVERY_PROTOCOL_SDP, "User Datagram Protocol (UDP)");
|
||||
map.put(USER_DATAGRAM_PROTOCOL_UDP, "Radio Frequency Communication Protocol (RFCOMM)");
|
||||
map.put(RADIO_FREQUENCY_COMMUNICATION_PROTOCOL_RFCOMM, "TCP");
|
||||
map.put(TCP, "TCSBIN");
|
||||
map.put(TCSBIN, "TCSAT");
|
||||
map.put(TCSAT, "Object Exchange Protocol (OBEX)");
|
||||
map.put(OBJECT_EXCHANGE_PROTOCOL_OBEX, "IP");
|
||||
map.put(IP, "FTP");
|
||||
map.put(FTP, "HTTP");
|
||||
map.put(HTTP, "WSP");
|
||||
map.put(WSP, "BNEP_SVC");
|
||||
map.put(BNEP_SVC, "UPNP Protocol");
|
||||
map.put(UPNP_PROTOCOL, "HIDP");
|
||||
map.put(HIDP, "Hardcopy Control Channel Protocol");
|
||||
map.put(HARDCOPY_CONTROL_CHANNEL_PROTOCOL, "Hardcopy Data Channel Protocol");
|
||||
map.put(HARDCOPY_DATA_CHANNEL_PROTOCOL, "Hardcopy Notification Protocol");
|
||||
map.put(HARDCOPY_NOTIFICATION_PROTOCOL, "VCTP Protocol");
|
||||
map.put(VCTP_PROTOCOL, "VDTP Protocol");
|
||||
map.put(VDTP_PROTOCOL, "CMPT Protocol");
|
||||
map.put(CMPT_PROTOCOL, "UDI C Plane Protocol");
|
||||
map.put(UDI_C_PLANE_PROTOCOL, "MCAP Control Channel");
|
||||
map.put(MCAP_CONTROL_CHANNEL, "MCAP Data Channel");
|
||||
map.put(MCAP_DATA_CHANNEL, "L2CAP");
|
||||
map.put(L2CAP, "Service Discovery Server");
|
||||
map.put(SERVICE_DISCOVERY_SERVER, "Browse Group Descriptor");
|
||||
map.put(BROWSE_GROUP_DESCRIPTOR, "Public Browse Group");
|
||||
map.put(PUBLIC_BROWSE_GROUP, "SPP");
|
||||
map.put(SPP, "LAN Access Using PPP");
|
||||
map.put(LAN_ACCESS_USING_PPP, "DUN_GW");
|
||||
map.put(DUN_GW, "OBEX_SYNC");
|
||||
map.put(OBEX_SYNC, "OBEX Object Push");
|
||||
map.put(OBEX_OBJECT_PUSH, "OBEX File Transfer");
|
||||
map.put(OBEX_FILE_TRANSFER, "IrMC Sync Command");
|
||||
map.put(IRMC_SYNC_COMMAND, "HSP_HS");
|
||||
map.put(HSP_HS, "Cordless Telephony");
|
||||
map.put(CORDLESS_TELEPHONY, "Audio Source");
|
||||
map.put(AUDIO_SOURCE, "Audio Sink");
|
||||
map.put(AUDIO_SINK, "AV Remote Control Target");
|
||||
map.put(AV_REMOTE_CONTROL_TARGET, "ADVANCED_AUDIO");
|
||||
map.put(ADVANCED_AUDIO, "AVRCP_REMOTE");
|
||||
map.put(AVRCP_REMOTE, "Video Conferencing");
|
||||
map.put(VIDEO_CONFERENCING, "Intercom");
|
||||
map.put(INTERCOM, "FAX");
|
||||
map.put(FAX, "Headset Profile (HSP) - Audio Gateway");
|
||||
map.put(HEADSET_PROFILE_HSP_AUDIO_GATEWAY, "WAP");
|
||||
map.put(WAP, "WAP Client");
|
||||
map.put(WAP_CLIENT, "PANU");
|
||||
map.put(PANU, "NAP");
|
||||
map.put(NAP, "GN");
|
||||
map.put(GN, "Direct Printing");
|
||||
map.put(DIRECT_PRINTING, "Reference Printing");
|
||||
map.put(REFERENCE_PRINTING, "Imaging");
|
||||
map.put(IMAGING, "Imaging Responder");
|
||||
map.put(IMAGING_RESPONDER, "Imaging Automatic Archive");
|
||||
map.put(IMAGING_AUTOMATIC_ARCHIVE, "Imaging Reference Objects");
|
||||
map.put(IMAGING_REFERENCE_OBJECTS, "Hands Free Profile (HFP)");
|
||||
map.put(HANDS_FREE_PROFILE_HFP, "Hands Free Profile (HFP) – Audio Gateway");
|
||||
map.put(HANDS_FREE_PROFILE_HFP_AUDIO_GATEWAY, "Direct Printing Reference Objects");
|
||||
map.put(DIRECT_PRINTING_REFERENCE_OBJECTS, "Reflected UI");
|
||||
map.put(REFLECTED_UI, "Basic Printing");
|
||||
map.put(BASIC_PRINTING, "Printing Status");
|
||||
map.put(PRINTING_STATUS, "HID");
|
||||
map.put(HID, "Hardcopy Cable Replacement");
|
||||
map.put(HARDCOPY_CABLE_REPLACEMENT, "HCR Print");
|
||||
map.put(HCR_PRINT, "HCR Scan");
|
||||
map.put(HCR_SCAN, "Common ISDN Access");
|
||||
map.put(COMMON_ISDN_ACCESS, "Video Conferencing Gateway");
|
||||
map.put(VIDEO_CONFERENCING_GATEWAY, "UDIMT");
|
||||
map.put(UDIMT, "UDITA");
|
||||
map.put(UDITA, "Audio Video");
|
||||
map.put(AUDIO_VIDEO, "SIM Access");
|
||||
map.put(SIM_ACCESS, "OBEX PCE");
|
||||
map.put(OBEX_PCE, "OBEX PSE");
|
||||
map.put(OBEX_PSE, "OBEX PBAP");
|
||||
map.put(OBEX_PBAP, "OBEX MAS");
|
||||
map.put(OBEX_MAS, "OBEX MNS");
|
||||
map.put(OBEX_MNS, "OBEX MAP");
|
||||
map.put(OBEX_MAP, "PNP");
|
||||
map.put(PNP, "Generic Networking");
|
||||
map.put(GENERIC_NETWORKING, "Generic File Transfer");
|
||||
map.put(GENERIC_FILE_TRANSFER, "Generic Audio");
|
||||
map.put(GENERIC_AUDIO, "Generic Telephony");
|
||||
map.put(GENERIC_TELEPHONY, "UPNP");
|
||||
map.put(UPNP, "UPNP IP");
|
||||
map.put(UPNP_IP, "ESDP UPnP IP PAN");
|
||||
map.put(ESDP_UPNP_IP_PAN, "ESDP UPnP IP LAP");
|
||||
map.put(ESDP_UPNP_IP_LAP, "ESDP Upnp L2CAP");
|
||||
map.put(ESDP_UPNP_L2CAP, "Video Distribution Profile (VDP) - Source");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SOURCE, "Video Distribution Profile (VDP) - Sink");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP_SINK, "Video Distribution Profile (VDP)");
|
||||
map.put(VIDEO_DISTRIBUTION_PROFILE_VDP, "Health Device Profile (HDP)");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP, "Health Device Profile (HDP) - Source");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SOURCE, "Health Device Profile (HDP) - Sink");
|
||||
map.put(HEALTH_DEVICE_PROFILE_HDP_SINK, "GAP");
|
||||
map.put(GAP, "GATT");
|
||||
map.put(GATT, "IMMEDIATE_ALERT");
|
||||
map.put(IMMEDIATE_ALERT, "LINK_LOSS");
|
||||
map.put(LINK_LOSS, "TX_POWER");
|
||||
map.put(TX_POWER, "Health Thermometer");
|
||||
map.put(HEALTH_THERMOMETER, "Device Information");
|
||||
map.put(DEVICE_INFORMATION, "HEART_RATE");
|
||||
map.put(HEART_RATE, "CYCLING_SC");
|
||||
map.put(CYCLING_SC, "CLIENT_CHARACTERISTIC_CONFIG");
|
||||
map.put(CLIENT_CHARACTERISTIC_CONFIG, "Device Name");
|
||||
map.put(DEVICE_NAME, "Appearance");
|
||||
map.put(APPEARANCE, "Peripheral Privacy Flag");
|
||||
map.put(PERIPHERAL_PRIVACY_FLAG, "Reconnection Address");
|
||||
map.put(RECONNECTION_ADDRESS, "Peripheral Preferred Connection Parameters");
|
||||
map.put(PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS, "Service Changed");
|
||||
map.put(SERVICE_CHANGED, "Alert Level");
|
||||
map.put(ALERT_LEVEL, "Tx Power Level");
|
||||
map.put(TX_POWER_LEVEL, "Date Time");
|
||||
map.put(DATE_TIME, "Day of Week");
|
||||
map.put(DAY_OF_WEEK, "Day Date Time");
|
||||
map.put(DAY_DATE_TIME, "Exact Time 256");
|
||||
map.put(EXACT_TIME_256, "DST Offset");
|
||||
map.put(DST_OFFSET, "Time Zone");
|
||||
map.put(TIME_ZONE, "Local Time Information");
|
||||
map.put(LOCAL_TIME_INFORMATION, "Time with DST");
|
||||
map.put(TIME_WITH_DST, "Time Accuracy");
|
||||
map.put(TIME_ACCURACY, "Time Source");
|
||||
map.put(TIME_SOURCE, "Reference Time Information");
|
||||
map.put(REFERENCE_TIME_INFORMATION, "Time Update Control Point");
|
||||
map.put(TIME_UPDATE_CONTROL_POINT, "Time Update State");
|
||||
map.put(TIME_UPDATE_STATE, "Temperature Measurement");
|
||||
map.put(TEMPERATURE_MEASUREMENT, "Temperature Type");
|
||||
map.put(TEMPERATURE_TYPE, "Intermediate Temperature");
|
||||
map.put(INTERMEDIATE_TEMPERATURE, "Measurement Interval");
|
||||
map.put(MEASUREMENT_INTERVAL, "System ID");
|
||||
map.put(SYSTEM_ID, "Model Number String");
|
||||
map.put(MODEL_NUMBER_STRING, "Serial Number String");
|
||||
map.put(SERIAL_NUMBER_STRING, "Firmware Revision String");
|
||||
map.put(FIRMWARE_REVISION_STRING, "Hardware Revision String");
|
||||
map.put(HARDWARE_REVISION_STRING, "Software Revision String");
|
||||
map.put(SOFTWARE_REVISION_STRING, "Manufacturer Name String");
|
||||
map.put(MANUFACTURER_NAME_STRING, "IEEE 11073-20601 Regulatory");
|
||||
map.put(IEEE_1107320601_REGULATORY, "Current Time");
|
||||
map.put(CURRENT_TIME, "Blood Pressure Measurement");
|
||||
map.put(BLOOD_PRESSURE_MEASUREMENT, "Intermediate Cuff Pressure");
|
||||
map.put(INTERMEDIATE_CUFF_PRESSURE, "Heart Rate Measurement");
|
||||
map.put(HEART_RATE_MEASUREMENT, "Body Sensor Location");
|
||||
map.put(BODY_SENSOR_LOCATION, "Heart Rate Control Point");
|
||||
map.put(HEART_RATE_CONTROL_POINT, "Alert Status");
|
||||
map.put(ALERT_STATUS, "Ringer Control Point");
|
||||
map.put(RINGER_CONTROL_POINT, "Ringer Setting");
|
||||
map.put(RINGER_SETTING, "Alert Category ID Bit Mask");
|
||||
map.put(ALERT_CATEGORY_ID_BIT_MASK, "Alert Category ID");
|
||||
map.put(ALERT_CATEGORY_ID, "Alert Notification Control Point");
|
||||
map.put(ALERT_NOTIFICATION_CONTROL_POINT, "Unread Alert Status");
|
||||
map.put(UNREAD_ALERT_STATUS, "New Alert");
|
||||
map.put(NEW_ALERT, "Supported New Alert Category");
|
||||
map.put(SUPPORTED_NEW_ALERT_CATEGORY, "Supported Unread Alert Category");
|
||||
map.put(SUPPORTED_UNREAD_ALERT_CATEGORY, "Blood Pressure Feature");
|
||||
map.put(BLOOD_PRESSURE_FEATURE, "PNPID");
|
||||
map.put(PNPID, "SC_CONTROL_POINT");
|
||||
map.put(SC_CONTROL_POINT, "CSC_MEASUREMENT");
|
||||
map.put(CSC_MEASUREMENT, "CSC_FEATURE");
|
||||
map.put(CSC_FEATURE, "SENSOR_LOCATION");
|
||||
map.put(SENSOR_LOCATION, "ActiveSync");
|
||||
map.put(ACTIVESYNC, "ActiveSync");
|
||||
map.put(ESTIMOTE_SERVICE, "Estimote Service");
|
||||
map.put(ESTIMOTE_UUID, "Estimote UUID");
|
||||
map.put(ESTIMOTE_MAJOR, "Estimote Major");
|
||||
map.put(ESTIMOTE_MINOR, "Estimote Minor");
|
||||
map.put(ESTIMOTE_BATTERY, "Estimote Battery");
|
||||
map.put(ESTIMOTE_TEMPERATURE, "Estimote Temperature");
|
||||
map.put(ESTIMOTE_POWER, "Estimote Power");
|
||||
map.put(ESTIMOTE_ADVERTISING_INTERVAL, "Estimote Advertising Interval");
|
||||
map.put(ESTIMOTE_VERSION_SERVICE, "Estimote Version Service");
|
||||
map.put(ESTIMOTE_SOFTWARE_VERSION, "Estimote Software Version");
|
||||
map.put(ESTIMOTE_HARDWARE_VERSION, "Estimote Hardware Version");
|
||||
map.put(ESTIMOTE_AUTHENTICATION_SERVICE, "Estimote Authentication Service");
|
||||
map.put(ESTIMOTE_ADVERTISING_SEED, "Estimote Advertising Seed");
|
||||
map.put(ESTIMOTE_ADVERTISING_VECTOR, "Estimote Advertising Vector");
|
||||
|
||||
|
||||
|
||||
return map;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -8,113 +11,117 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.util.SparseArray;
|
||||
|
||||
public class AdRecordUtils {
|
||||
|
||||
public static String getRecordDataAsString(final AdRecord nameRecord) {
|
||||
if(nameRecord == null){return "";}
|
||||
return new String(nameRecord.getData());
|
||||
}
|
||||
public static String getRecordDataAsString(final AdRecord nameRecord) {
|
||||
if (nameRecord == null) {
|
||||
return "";
|
||||
}
|
||||
return new String(nameRecord.getData());
|
||||
}
|
||||
|
||||
public static byte[] getServiceData(final AdRecord serviceData) {
|
||||
if (serviceData == null) {return null;}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null;
|
||||
public static byte[] getServiceData(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return null;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return null;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Chop out the uuid
|
||||
return Arrays.copyOfRange(raw, 2, raw.length);
|
||||
}
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Chop out the uuid
|
||||
return Arrays.copyOfRange(raw, 2, raw.length);
|
||||
}
|
||||
|
||||
public static int getServiceDataUuid(final AdRecord serviceData) {
|
||||
if (serviceData == null) {return -1;}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1;
|
||||
public static int getServiceDataUuid(final AdRecord serviceData) {
|
||||
if (serviceData == null) {
|
||||
return -1;
|
||||
}
|
||||
if (serviceData.getType() != AdRecord.TYPE_SERVICE_DATA) return -1;
|
||||
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Find UUID data in byte array
|
||||
int uuid = (raw[1] & 0xFF) << 8;
|
||||
uuid += (raw[0] & 0xFF);
|
||||
final byte[] raw = serviceData.getData();
|
||||
//Find UUID data in byte array
|
||||
int uuid = (raw[1] & 0xFF) << 8;
|
||||
uuid += (raw[0] & 0xFF);
|
||||
|
||||
return uuid;
|
||||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read out all the AD structures from the raw scan record
|
||||
*/
|
||||
public static List<AdRecord> parseScanRecordAsList(final byte[] scanRecord) {
|
||||
final List<AdRecord> records = new ArrayList<AdRecord>();
|
||||
/*
|
||||
* Read out all the AD structures from the raw scan record
|
||||
*/
|
||||
public static List<AdRecord> parseScanRecordAsList(final byte[] scanRecord) {
|
||||
final List<AdRecord> records = new ArrayList<AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.add(new AdRecord(length, type, data));
|
||||
records.add(new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(records);
|
||||
}
|
||||
return Collections.unmodifiableList(records);
|
||||
}
|
||||
|
||||
@SuppressLint("UseSparseArrays")
|
||||
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
|
||||
final Map<Integer, AdRecord> records = new HashMap<Integer, AdRecord>();
|
||||
@SuppressLint("UseSparseArrays")
|
||||
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
|
||||
final Map<Integer, AdRecord> records = new HashMap<Integer, AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(records);
|
||||
}
|
||||
return Collections.unmodifiableMap(records);
|
||||
}
|
||||
|
||||
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(final byte[] scanRecord) {
|
||||
final SparseArray<AdRecord> records = new SparseArray<AdRecord>();
|
||||
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(final byte[] scanRecord) {
|
||||
final SparseArray<AdRecord> records = new SparseArray<AdRecord>();
|
||||
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
int index = 0;
|
||||
while (index < scanRecord.length) {
|
||||
final int length = scanRecord[index++];
|
||||
//Done once we run out of records
|
||||
if (length == 0) break;
|
||||
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
final int type = ByteUtils.getIntFromByte(scanRecord[index]);
|
||||
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
//Done if our record isn't a valid type
|
||||
if (type == 0) break;
|
||||
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index+1, index+length);
|
||||
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
|
||||
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
records.put(type, new AdRecord(length, type, data));
|
||||
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
//Advance
|
||||
index += length;
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,121 +4,124 @@ import java.nio.ByteBuffer;
|
||||
|
||||
public class ByteUtils {
|
||||
|
||||
/** The Constant HEXES. */
|
||||
private static final String HEXES = "0123456789ABCDEF";
|
||||
/**
|
||||
* The Constant HEXES.
|
||||
*/
|
||||
private static final String HEXES = "0123456789ABCDEF";
|
||||
|
||||
/**
|
||||
* Gets a pretty representation of a Byte Array as a HEX String.
|
||||
*
|
||||
* Sample output: [01, 30, FF, AA]
|
||||
*
|
||||
* @param array the array
|
||||
* @return the string
|
||||
*/
|
||||
public static String byteArrayToHexString(final byte[] array){
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean firstEntry = true;
|
||||
sb.append('[');
|
||||
/**
|
||||
* Gets a pretty representation of a Byte Array as a HEX String.
|
||||
* <p/>
|
||||
* Sample output: [01, 30, FF, AA]
|
||||
*
|
||||
* @param array the array
|
||||
* @return the string
|
||||
*/
|
||||
public static String byteArrayToHexString(final byte[] array) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
boolean firstEntry = true;
|
||||
sb.append('[');
|
||||
|
||||
for ( final byte b : array ) {
|
||||
if(!firstEntry){
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(HEXES.charAt((b & 0xF0) >> 4));
|
||||
sb.append(HEXES.charAt((b & 0x0F)));
|
||||
firstEntry = false;
|
||||
}
|
||||
for (final byte b : array) {
|
||||
if (!firstEntry) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(HEXES.charAt((b & 0xF0) >> 4));
|
||||
sb.append(HEXES.charAt((b & 0x0F)));
|
||||
firstEntry = false;
|
||||
}
|
||||
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a byte arry starts with another byte array.
|
||||
*
|
||||
* @param array the array
|
||||
* @param prefix the prefix
|
||||
* @return true, if successful
|
||||
*/
|
||||
public static boolean doesArrayBeginWith(final byte[] array, final byte[] prefix){
|
||||
if(array.length < prefix.length){return false;}
|
||||
/**
|
||||
* Checks to see if a byte arry starts with another byte array.
|
||||
*
|
||||
* @param array the array
|
||||
* @param prefix the prefix
|
||||
* @return true, if successful
|
||||
*/
|
||||
public static boolean doesArrayBeginWith(final byte[] array, final byte[] prefix) {
|
||||
if (array.length < prefix.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < prefix.length; i++){
|
||||
if(array[i] != prefix[i]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < prefix.length; i++) {
|
||||
if (array[i] != prefix[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array with a length of 2 into an int
|
||||
*
|
||||
* @param input the input
|
||||
* @return the int from the array
|
||||
*/
|
||||
public static int getIntFrom2ByteArray(final byte[] input){
|
||||
final byte[] result = new byte[4];
|
||||
/**
|
||||
* Converts a byte array with a length of 2 into an int
|
||||
*
|
||||
* @param input the input
|
||||
* @return the int from the array
|
||||
*/
|
||||
public static int getIntFrom2ByteArray(final byte[] input) {
|
||||
final byte[] result = new byte[4];
|
||||
|
||||
result[0] = 0;
|
||||
result[1] = 0;
|
||||
result[2] = input[0];
|
||||
result[3] = input[1];
|
||||
result[0] = 0;
|
||||
result[1] = 0;
|
||||
result[2] = input[0];
|
||||
result[3] = input[1];
|
||||
|
||||
return ByteUtils.getIntFromByteArray(result);
|
||||
}
|
||||
return ByteUtils.getIntFromByteArray(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte to an int, preserving the sign.
|
||||
*
|
||||
* For example, FF will be converted to 255 and not -1.
|
||||
*
|
||||
* @param bite the bite
|
||||
* @return the int from byte
|
||||
*/
|
||||
public static int getIntFromByte(final byte bite){
|
||||
return Integer.valueOf(bite & 0xFF);
|
||||
}
|
||||
/**
|
||||
* Converts a byte to an int, preserving the sign.
|
||||
* <p/>
|
||||
* For example, FF will be converted to 255 and not -1.
|
||||
*
|
||||
* @param bite the bite
|
||||
* @return the int from byte
|
||||
*/
|
||||
public static int getIntFromByte(final byte bite) {
|
||||
return Integer.valueOf(bite & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to an int.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the int from byte array
|
||||
*/
|
||||
public static int getIntFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getInt();
|
||||
}
|
||||
/**
|
||||
* Converts a byte array to an int.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the int from byte array
|
||||
*/
|
||||
public static int getIntFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a byte array to a long.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the long from byte array
|
||||
*/
|
||||
public static long getLongFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getLong();
|
||||
}
|
||||
/**
|
||||
* Converts a byte array to a long.
|
||||
*
|
||||
* @param bytes the bytes
|
||||
* @return the long from byte array
|
||||
*/
|
||||
public static long getLongFromByteArray(final byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes).getLong();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverts an array
|
||||
*
|
||||
* @param array the array
|
||||
* @return the byte[]
|
||||
*/
|
||||
public static byte[] invertArray(final byte[] array){
|
||||
final int size = array.length;
|
||||
byte temp;
|
||||
/**
|
||||
* Inverts an array
|
||||
*
|
||||
* @param array the array
|
||||
* @return the byte[]
|
||||
*/
|
||||
public static byte[] invertArray(final byte[] array) {
|
||||
final int size = array.length;
|
||||
byte temp;
|
||||
|
||||
for (int i = 0; i < size/2; i++)
|
||||
{
|
||||
temp = array[i];
|
||||
array[i] = array[size-1 - i];
|
||||
array[size-1 - i] = temp;
|
||||
}
|
||||
for (int i = 0; i < size / 2; i++) {
|
||||
temp = array[i];
|
||||
array[i] = array[size - 1 - i];
|
||||
array[size - 1 - i] = temp;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package uk.co.alt236.bluetoothlelib.util;
|
||||
|
||||
public enum IBeaconDistanceDescriptor {
|
||||
IMMEDIATE,
|
||||
NEAR,
|
||||
FAR,
|
||||
UNKNOWN,
|
||||
}
|
||||
@@ -4,86 +4,83 @@ import uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice;
|
||||
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
|
||||
|
||||
public class IBeaconUtils {
|
||||
private static final double DISTANCE_THRESHOLD_WTF = 0.0;
|
||||
private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
|
||||
private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
|
||||
private static final double DISTANCE_THRESHOLD_WTF = 0.0;
|
||||
private static final double DISTANCE_THRESHOLD_IMMEDIATE = 0.5;
|
||||
private static final double DISTANCE_THRESHOLD_NEAR = 3.0;
|
||||
|
||||
private static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = new byte[]{0x4C, 0x00, 0x02, 0x15};
|
||||
private static final byte[] MANUFACTURER_DATA_IBEACON_PREFIX = new byte[]{0x4C, 0x00, 0x02, 0x15};
|
||||
|
||||
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy){
|
||||
if(accuracy < DISTANCE_THRESHOLD_WTF){
|
||||
return IBeaconDistanceDescriptor.UNKNOWN;
|
||||
}
|
||||
/**
|
||||
* Calculates the accuracy of an RSSI reading.
|
||||
* <p/>
|
||||
* The code was taken from {@linktourl http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing}
|
||||
*
|
||||
* @param txPower the calibrated TX power of an iBeacon
|
||||
* @param rssi the RSSI value of the iBeacon
|
||||
* @return the calculated Accuracy
|
||||
*/
|
||||
public static double calculateAccuracy(final int txPower, final double rssi) {
|
||||
if (rssi == 0) {
|
||||
return -1.0; // if we cannot determine accuracy, return -1.
|
||||
}
|
||||
|
||||
if(accuracy < DISTANCE_THRESHOLD_IMMEDIATE){
|
||||
return IBeaconDistanceDescriptor.IMMEDIATE;
|
||||
}
|
||||
final double ratio = rssi * 1.0 / txPower;
|
||||
if (ratio < 1.0) {
|
||||
return Math.pow(ratio, 10);
|
||||
} else {
|
||||
final double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111;
|
||||
return accuracy;
|
||||
}
|
||||
}
|
||||
|
||||
if(accuracy < DISTANCE_THRESHOLD_NEAR){
|
||||
return IBeaconDistanceDescriptor.NEAR;
|
||||
}
|
||||
public static IBeaconDistanceDescriptor getDistanceDescriptor(final double accuracy) {
|
||||
if (accuracy < DISTANCE_THRESHOLD_WTF) {
|
||||
return IBeaconDistanceDescriptor.UNKNOWN;
|
||||
}
|
||||
|
||||
return IBeaconDistanceDescriptor.FAR;
|
||||
}
|
||||
if (accuracy < DISTANCE_THRESHOLD_IMMEDIATE) {
|
||||
return IBeaconDistanceDescriptor.IMMEDIATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the accuracy of an RSSI reading.
|
||||
*
|
||||
* The code was taken from {@linktourl http://stackoverflow.com/questions/20416218/understanding-ibeacon-distancing}
|
||||
*
|
||||
* @param txPower the calibrated TX power of an iBeacon
|
||||
* @param rssi the RSSI value of the iBeacon
|
||||
* @return the calculated Accuracy
|
||||
*/
|
||||
public static double calculateAccuracy(final int txPower, final double rssi) {
|
||||
if (rssi == 0) {
|
||||
return -1.0; // if we cannot determine accuracy, return -1.
|
||||
}
|
||||
if (accuracy < DISTANCE_THRESHOLD_NEAR) {
|
||||
return IBeaconDistanceDescriptor.NEAR;
|
||||
}
|
||||
|
||||
final double ratio = rssi*1.0/txPower;
|
||||
if (ratio < 1.0) {
|
||||
return Math.pow(ratio,10);
|
||||
}
|
||||
else {
|
||||
final double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
|
||||
return accuracy;
|
||||
}
|
||||
}
|
||||
return IBeaconDistanceDescriptor.FAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
|
||||
*
|
||||
* @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
|
||||
* @return true if the device is an iBeacon, false otherwise
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(final BluetoothLeDevice device){
|
||||
return isThisAnIBeacon(
|
||||
device.getAdRecordStore().getRecordDataAsString(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getBytes());
|
||||
}
|
||||
/**
|
||||
* Ascertains whether a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} is an iBeacon;
|
||||
*
|
||||
* @param device a {@link uk.co.alt236.bluetoothlelib.device.BluetoothLeDevice} device.
|
||||
* @return true if the device is an iBeacon, false otherwise
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(final BluetoothLeDevice device) {
|
||||
return isThisAnIBeacon(
|
||||
device.getAdRecordStore().getRecordDataAsString(AdRecord.TYPE_MANUFACTURER_SPECIFIC_DATA).getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether a Manufacturer Data byte array belongs to an iBeacon;
|
||||
*
|
||||
* @param manufacturerData a Bluetooth LE device's raw manufacturerData.
|
||||
* @return true if the manufacturer data belong to an iBeacon
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(final byte[] manufacturerData){
|
||||
if(manufacturerData == null){return false;}
|
||||
/**
|
||||
* Ascertains whether a Manufacturer Data byte array belongs to an iBeacon;
|
||||
*
|
||||
* @param manufacturerData a Bluetooth LE device's raw manufacturerData.
|
||||
* @return true if the manufacturer data belong to an iBeacon
|
||||
*/
|
||||
public static boolean isThisAnIBeacon(final byte[] manufacturerData) {
|
||||
if (manufacturerData == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// An iBeacon record must be at least 25 chars long
|
||||
if(!(manufacturerData.length >= 25)){return false;}
|
||||
// An iBeacon record must be at least 25 chars long
|
||||
if (!(manufacturerData.length >= 25)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ByteUtils.doesArrayBeginWith(manufacturerData, MANUFACTURER_DATA_IBEACON_PREFIX)){
|
||||
return true;
|
||||
}
|
||||
if (ByteUtils.doesArrayBeginWith(manufacturerData, MANUFACTURER_DATA_IBEACON_PREFIX)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public enum IBeaconDistanceDescriptor{
|
||||
IMMEDIATE,
|
||||
NEAR,
|
||||
FAR,
|
||||
UNKNOWN,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,18 @@ package uk.co.alt236.bluetoothlelib.util;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V>{
|
||||
private static final long serialVersionUID = -5375660288461724925L;
|
||||
public class LimitedLinkHashMap<K, V> extends LinkedHashMap<K, V> {
|
||||
private static final long serialVersionUID = -5375660288461724925L;
|
||||
|
||||
private final int mMaxSize;
|
||||
private final int mMaxSize;
|
||||
|
||||
public LimitedLinkHashMap(final int maxSize){
|
||||
super(maxSize + 1, 1, false);
|
||||
mMaxSize = maxSize;
|
||||
}
|
||||
public LimitedLinkHashMap(final int maxSize) {
|
||||
super(maxSize + 1, 1, false);
|
||||
mMaxSize = maxSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeEldestEntry(final Map.Entry<K, V> eldest) {
|
||||
return this.size() > mMaxSize;
|
||||
return this.size() > mMaxSize;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user