use of android.os.ParcelUuid in project android_frameworks_base by DirtyUnicorns.
the class ScanFilterTest method testsetServiceDataFilter.
@SmallTest
public void testsetServiceDataFilter() {
byte[] setServiceData = new byte[] { 0x50, 0x64 };
ParcelUuid serviceDataUuid = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
assertTrue("service data filter fails", filter.matches(mScanResult));
byte[] emptyData = new byte[0];
filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build();
assertTrue("service data filter fails", filter.matches(mScanResult));
byte[] prefixData = new byte[] { 0x50 };
filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build();
assertTrue("service data filter fails", filter.matches(mScanResult));
byte[] nonMatchData = new byte[] { 0x51, 0x64 };
byte[] mask = new byte[] { (byte) 0x00, (byte) 0xFF };
filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build();
assertTrue("partial service data filter fails", filter.matches(mScanResult));
filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
assertFalse("service data filter fails", filter.matches(mScanResult));
}
use of android.os.ParcelUuid in project android_frameworks_base by DirtyUnicorns.
the class BluetoothAdapter method startLeScan.
/**
* Starts a scan for Bluetooth LE devices, looking for devices that
* advertise given services.
*
* <p>Devices which advertise all specified services are reported using the
* {@link LeScanCallback#onLeScan} callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
*
* @param serviceUuids Array of services to look for
* @param callback the callback LE scan results are delivered
* @return true, if the scan was started successfully
* @deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)}
* instead.
*/
@Deprecated
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
if (DBG)
Log.d(TAG, "startLeScan(): " + Arrays.toString(serviceUuids));
if (callback == null) {
if (DBG)
Log.e(TAG, "startLeScan: null callback");
return false;
}
BluetoothLeScanner scanner = getBluetoothLeScanner();
if (scanner == null) {
if (DBG)
Log.e(TAG, "startLeScan: cannot get BluetoothLeScanner");
return false;
}
synchronized (mLeScanClients) {
if (mLeScanClients.containsKey(callback)) {
if (DBG)
Log.e(TAG, "LE Scan has already started");
return false;
}
try {
IBluetoothGatt iGatt = mManagerService.getBluetoothGatt();
if (iGatt == null) {
// BLE is not supported
return false;
}
ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
if (callbackType != ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
// Should not happen.
Log.e(TAG, "LE Scan has already started");
return;
}
ScanRecord scanRecord = result.getScanRecord();
if (scanRecord == null) {
return;
}
if (serviceUuids != null) {
List<ParcelUuid> uuids = new ArrayList<ParcelUuid>();
for (UUID uuid : serviceUuids) {
uuids.add(new ParcelUuid(uuid));
}
List<ParcelUuid> scanServiceUuids = scanRecord.getServiceUuids();
if (scanServiceUuids == null || !scanServiceUuids.containsAll(uuids)) {
if (DBG)
Log.d(TAG, "uuids does not match");
return;
}
}
callback.onLeScan(result.getDevice(), result.getRssi(), scanRecord.getBytes());
}
};
ScanSettings settings = new ScanSettings.Builder().setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
List<ScanFilter> filters = new ArrayList<ScanFilter>();
if (serviceUuids != null && serviceUuids.length > 0) {
// Note scan filter does not support matching an UUID array so we put one
// UUID to hardware and match the whole array in callback.
ScanFilter filter = new ScanFilter.Builder().setServiceUuid(new ParcelUuid(serviceUuids[0])).build();
filters.add(filter);
}
scanner.startScan(filters, settings, scanCallback);
mLeScanClients.put(callback, scanCallback);
return true;
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
}
return false;
}
use of android.os.ParcelUuid in project android_frameworks_base by DirtyUnicorns.
the class BluetoothGatt method registerApp.
/**
* Register an application callback to start using GATT.
*
* <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
* is used to notify success or failure if the function returns true.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
*
* @param callback GATT callback handler that will receive asynchronous callbacks.
* @return If true, the callback will be called to notify success or failure,
* false on immediate error
*/
private boolean registerApp(BluetoothGattCallback callback) {
if (DBG)
Log.d(TAG, "registerApp()");
if (mService == null)
return false;
mCallback = callback;
UUID uuid = UUID.randomUUID();
if (DBG)
Log.d(TAG, "registerApp() - UUID=" + uuid);
try {
mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
} catch (RemoteException e) {
Log.e(TAG, "", e);
return false;
}
return true;
}
use of android.os.ParcelUuid in project android_frameworks_base by DirtyUnicorns.
the class ScanRecord method parseFromBytes.
/**
* Parse scan record bytes to {@link ScanRecord}.
* <p>
* The format is defined in Bluetooth 4.1 specification, Volume 3, Part C, Section 11 and 18.
* <p>
* All numerical multi-byte entities and values shall use little-endian <strong>byte</strong>
* order.
*
* @param scanRecord The scan record of Bluetooth LE advertisement and/or scan response.
* @hide
*/
public static ScanRecord parseFromBytes(byte[] scanRecord) {
if (scanRecord == null) {
return null;
}
int currentPos = 0;
int advertiseFlag = -1;
List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
String localName = null;
int txPowerLevel = Integer.MIN_VALUE;
SparseArray<byte[]> manufacturerData = new SparseArray<byte[]>();
Map<ParcelUuid, byte[]> serviceData = new ArrayMap<ParcelUuid, byte[]>();
try {
while (currentPos < scanRecord.length) {
// length is unsigned int.
int length = scanRecord[currentPos++] & 0xFF;
if (length == 0) {
break;
}
// Note the length includes the length of the field type itself.
int dataLength = length - 1;
// fieldType is unsigned int.
int fieldType = scanRecord[currentPos++] & 0xFF;
switch(fieldType) {
case DATA_TYPE_FLAGS:
advertiseFlag = scanRecord[currentPos] & 0xFF;
break;
case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_16_BIT, serviceUuids);
break;
case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_32_BIT, serviceUuids);
break;
case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
parseServiceUuid(scanRecord, currentPos, dataLength, BluetoothUuid.UUID_BYTES_128_BIT, serviceUuids);
break;
case DATA_TYPE_LOCAL_NAME_SHORT:
case DATA_TYPE_LOCAL_NAME_COMPLETE:
localName = new String(extractBytes(scanRecord, currentPos, dataLength));
break;
case DATA_TYPE_TX_POWER_LEVEL:
txPowerLevel = scanRecord[currentPos];
break;
case DATA_TYPE_SERVICE_DATA:
// The first two bytes of the service data are service data UUID in little
// endian. The rest bytes are service data.
int serviceUuidLength = BluetoothUuid.UUID_BYTES_16_BIT;
byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos, serviceUuidLength);
ParcelUuid serviceDataUuid = BluetoothUuid.parseUuidFrom(serviceDataUuidBytes);
byte[] serviceDataArray = extractBytes(scanRecord, currentPos + serviceUuidLength, dataLength - serviceUuidLength);
serviceData.put(serviceDataUuid, serviceDataArray);
break;
case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
// The first two bytes of the manufacturer specific data are
// manufacturer ids in little endian.
int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8) + (scanRecord[currentPos] & 0xFF);
byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2, dataLength - 2);
manufacturerData.put(manufacturerId, manufacturerDataBytes);
break;
default:
// Just ignore, we don't handle such data type.
break;
}
currentPos += dataLength;
}
if (serviceUuids.isEmpty()) {
serviceUuids = null;
}
return new ScanRecord(serviceUuids, manufacturerData, serviceData, advertiseFlag, txPowerLevel, localName, scanRecord);
} catch (Exception e) {
Log.e(TAG, "unable to parse scan record: " + Arrays.toString(scanRecord));
// and return an empty record with raw scanRecord bytes in results
return new ScanRecord(null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
}
}
use of android.os.ParcelUuid in project android_frameworks_base by DirtyUnicorns.
the class BluetoothLeAdvertiser method totalBytes.
// Compute the size of advertisement data or scan resp
private int totalBytes(AdvertiseData data, boolean isFlagsIncluded) {
if (data == null)
return 0;
// Flags field is omitted if the advertising is not connectable.
int size = (isFlagsIncluded) ? FLAGS_FIELD_BYTES : 0;
if (data.getServiceUuids() != null) {
int num16BitUuids = 0;
int num32BitUuids = 0;
int num128BitUuids = 0;
for (ParcelUuid uuid : data.getServiceUuids()) {
if (BluetoothUuid.is16BitUuid(uuid)) {
++num16BitUuids;
} else if (BluetoothUuid.is32BitUuid(uuid)) {
++num32BitUuids;
} else {
++num128BitUuids;
}
}
// 16 bit service uuids are grouped into one field when doing advertising.
if (num16BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD + num16BitUuids * BluetoothUuid.UUID_BYTES_16_BIT;
}
// 32 bit service uuids are grouped into one field when doing advertising.
if (num32BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD + num32BitUuids * BluetoothUuid.UUID_BYTES_32_BIT;
}
// 128 bit service uuids are grouped into one field when doing advertising.
if (num128BitUuids != 0) {
size += OVERHEAD_BYTES_PER_FIELD + num128BitUuids * BluetoothUuid.UUID_BYTES_128_BIT;
}
}
for (ParcelUuid uuid : data.getServiceData().keySet()) {
size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH + byteLength(data.getServiceData().get(uuid));
}
for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
size += OVERHEAD_BYTES_PER_FIELD + MANUFACTURER_SPECIFIC_DATA_LENGTH + byteLength(data.getManufacturerSpecificData().valueAt(i));
}
if (data.getIncludeTxPowerLevel()) {
// tx power level value is one byte.
size += OVERHEAD_BYTES_PER_FIELD + 1;
}
if (data.getIncludeDeviceName() && mBluetoothAdapter.getName() != null) {
size += OVERHEAD_BYTES_PER_FIELD + mBluetoothAdapter.getName().length();
}
return size;
}
Aggregations