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;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import uk.co.alt236.bluetoothlelib.device.adrecord.AdRecord;
public final class AdRecordUtils {
private AdRecordUtils(){
// TO AVOID INSTANTIATION
}
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;
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;
final byte[] raw = serviceData.getData();
//Find UUID data in byte array
int uuid = (raw[1] & 0xFF) << 8;
uuid += (raw[0] & 0xFF);
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<>();
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]);
//Done if our record isn't a valid type
if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.add(new AdRecord(length, type, data));
//Advance
index += length;
}
return Collections.unmodifiableList(records);
}
@SuppressLint("UseSparseArrays")
public static Map<Integer, AdRecord> parseScanRecordAsMap(final byte[] scanRecord) {
final Map<Integer, AdRecord> records = new HashMap<>();
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]);
//Done if our record isn't a valid type
if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.put(type, new AdRecord(length, type, data));
//Advance
index += length;
}
return Collections.unmodifiableMap(records);
}
public static SparseArray<AdRecord> parseScanRecordAsSparseArray(final byte[] scanRecord) {
final SparseArray<AdRecord> records = new SparseArray<>();
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]);
//Done if our record isn't a valid type
if (type == 0) break;
final byte[] data = Arrays.copyOfRange(scanRecord, index + 1, index + length);
records.put(type, new AdRecord(length, type, data));
//Advance
index += length;
}
return records;
}
}