Open P0labrD opened 1 day ago
they should not be different. please open a PR if there is a bug.
msd
= list of full raw data, split by manufacturer
manufacturerData
= map of <manufactureId, data without manufactureId>
also, where is this json coming from?
please print out the advertisement data directly and report back
print(advertisementData)
@override
String toString() {
return 'AdvertisementData{'
'advName: $advName, '
'txPowerLevel: $txPowerLevel, '
'appearance: $appearance, '
'connectable: $connectable, '
'manufacturerData: $manufacturerData, '
'serviceData: $serviceData, '
'serviceUuids: $serviceUuids'
'}';
}
I wrote the json with what I saw in my debugger, anonymizing the data Here's the real (still anonymized) print ouput for iOS:
flutter: AdvertisementData{advName: product-name, txPowerLevel: null, appearance: null, connectable: true, manufacturerData: {12345: [0, 0, 5, 54, 48, 48, 85, 48, 54, 57, 48, 57, 50, 49]}, serviceData: {}, serviceUuids: []}
And for Android:
I/flutter (19040): AdvertisementData{advName: product-name, txPowerLevel: null, appearance: null, connectable: true, manufacturerData: {0: [5, 54, 48, 48, 85, 48, 54, 57, 48, 57, 50, 49], 12345: []}, serviceData: {}, serviceUuids: []}
So if I understand correctly, my device is seen with one manufacturerId 12345
for iOS, but with two for android, 0
and 12345
, but with the rawData being on the wrong side
I'm not a hardware developer myself, but I could ask the one who did develop on the chip what he implemented in order to give good reproduction info.
Here's the plugin method I call to start scanning:
FlutterBluePlus.startScan(
timeout: timeout,
withMsd: [MsdFilter(12345)],
removeIfGone: const Duration(seconds: 3),
continuousUpdates: true,
);
the android code is here. you should debug it further :)
particularly, you should print the result of : byte[] bytes = adv.getBytes();
it probably has a bug. iOS is probably correct.
Map<Integer, byte[]> getManufacturerSpecificData(ScanRecord adv) {
byte[] bytes = adv.getBytes();
Map<Integer, byte[]> manufacturerDataMap = new HashMap<>();
int n = 0;
while (n < bytes.length) {
// layout:
// n[0] = fieldlen
// n[1] = datatype (MSD)
// n[2] = manufacturerId (low)
// n[3] = manufacturerId (high)
// n[4] = data...
int fieldLen = bytes[n] & 0xFF;
// no more or malformed data
if (fieldLen <= 0) {
break;
}
// Ensuring we don't go past the bytes array
if (n + fieldLen >= bytes.length) {
break;
}
int dataType = bytes[n + 1] & 0xFF;
// Manufacturer Specific Data magic number
// At least 3 bytes: 2 for manufacturer ID & 1 for dataType
if (dataType == 0xFF && fieldLen >= 3) {
// Manufacturer Id
int high = (bytes[n + 3] & 0xFF) << 8;
int low = (bytes[n + 2] & 0xFF);
int manufacturerId = high | low;
// the length of the msd data,
// excluding manufacturerId & dataType
int msdLen = fieldLen - 3;
// ptr to msd data
// excluding manufacturerId & dataType
int msdPtr = n + 4;
// add to map
if (manufacturerDataMap.containsKey(manufacturerId)) {
// If the manufacturer ID already exists, append the new data to the existing list
byte[] existingData = manufacturerDataMap.get(manufacturerId);
byte[] mergedData = new byte[existingData.length + msdLen];
// Merge arrays
System.arraycopy(existingData, 0, mergedData, 0, existingData.length);
System.arraycopy(bytes, msdPtr, mergedData, existingData.length, msdLen);
manufacturerDataMap.put(manufacturerId, mergedData);
} else {
// Otherwise, put the new manufacturer ID and its data into the map
byte[] data = new byte[msdLen];
// Starting from n+4 because manufacturerId occupies n+2 and n+3
System.arraycopy(bytes, msdPtr, data, 0, data.length);
manufacturerDataMap.put(manufacturerId, data);
}
}
n += fieldLen + 1;
}
return manufacturerDataMap;
}
@MrCsabaToth
Requirements
Have you checked this problem on the example app?
No
FlutterBluePlus Version
1.33.2
Flutter Version
3.24.3
What OS?
Android, iOS
OS Version
iOS 15.8.3, Android 14
Bluetooth Module
ESP32-WROOM-32E
What is your problem?
I'm looking at the
advertisementData
of my bluetooth device on both Android and iOS, and I can't figure why the format ofmanufacturerData
andmsd
properties are different: themanufacturerId
key is accessed differently between both osI can't find any documentation on this difference, so before introducing platform specific code in production, I would like to be sure it is developed as intented.
Thank you very much!
Logs