Fix wrong manufacturer data in release mode (#24)

* Fix wrong manufacturer data in release mode

* Improve code

* fix manufacturer data for little endian

* Minor fix

---------

Co-authored-by: Rohit Sangwan <rohitsangwan647@gmail.com>
This commit is contained in:
Foti Dim
2024-03-18 18:16:16 +01:00
committed by GitHub
parent fe0a654f36
commit 580fca6e4a
8 changed files with 147 additions and 47 deletions
+34
View File
@@ -44,4 +44,38 @@ namespace universal_ble
poweredOn = 5,
};
enum class AdvertisementSectionType : uint8_t
{
Flags = 0x01,
IncompleteService16BitUuids = 0x02,
CompleteService16BitUuids = 0x03,
IncompleteService32BitUuids = 0x04,
CompleteService32BitUuids = 0x05,
IncompleteService128BitUuids = 0x06,
CompleteService128BitUuids = 0x07,
ShortenedLocalName = 0x08,
CompleteLocalName = 0x09,
TxPowerLevel = 0x0A,
ClassOfDevice = 0x0D,
SimplePairingHashC192 = 0x0E,
SecurityManagerTKValues = 0x10,
SecurityManagerOutOfBandFlags = 0x11,
SlaveConnectionIntervalRange = 0x12,
ServiceSolicitation16BitUuids = 0x14,
ServiceSolicitation32BitUuids = 0x1F,
ServiceSolicitation128BitUuids = 0x15,
ServiceData16BitUuids = 0x16,
ServiceData32BitUuids = 0x20,
ServiceData128BitUuids = 0x21,
PublicTargetAddress = 0x17,
RandomTargetAddress = 0x18,
Appearance = 0x19,
AdvertisingInterval = 0x1A,
LEBluetoothDeviceAddress = 0x1B,
LERole = 0x1C,
SimplePairingHashC256 = 0x1D,
ThreeDimensionInformationData = 0x3D,
ManufacturerSpecificData = 0xFF,
};
} // namespace universal_ble
+7
View File
@@ -119,4 +119,11 @@ namespace universal_ble
return std::string{chars};
}
bool isLittleEndian()
{
uint16_t number = 0x1;
char *numPtr = (char *)&number;
return (numPtr[0] == 1);
}
} // namespace SimpleBLE
+1
View File
@@ -25,6 +25,7 @@ namespace universal_ble
std::string to_hexstring(std::vector<uint8_t> bytes);
std::string to_uuidstr(winrt::guid guid);
bool isLittleEndian();
/// To call async functions synchronously
template <typename async_t>
+41 -24
View File
@@ -32,12 +32,6 @@ namespace universal_ble
std::unique_ptr<UniversalBleCallbackChannel> callbackChannel;
std::unordered_map<std::string, winrt::event_token> characteristicsTokens{}; // TODO: Remove the map and store the token inside the characteristic object object
union uint16_t_union
{
uint16_t uint16;
byte bytes[sizeof(uint16_t)];
};
void UniversalBlePlugin::RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar)
{
auto plugin = std::make_unique<UniversalBlePlugin>(registrar);
@@ -478,24 +472,46 @@ namespace universal_ble
{
try
{
if (advertisement == nullptr)
return {};
if (advertisement.ManufacturerData().Size() == 0)
{
return std::vector<uint8_t>();
}
return {};
auto manufacturerData = advertisement.ManufacturerData().GetAt(0);
// FIXME Compat with REG_DWORD_BIG_ENDIAN
uint8_t *prefix = uint16_t_union{manufacturerData.CompanyId()}.bytes;
auto result = std::vector<uint8_t>{prefix, prefix + sizeof(uint16_t_union)};
if (manufacturerData == nullptr)
return {};
uint16_t companyId = manufacturerData.CompanyId();
uint8_t prefix[2];
auto leastSignificantBit = static_cast<uint8_t>(companyId & 0xFF);
auto mostSignificantBit = static_cast<uint8_t>(companyId >> 8);
if (isLittleEndian())
{
prefix[0] = leastSignificantBit;
prefix[1] = mostSignificantBit;
}
else
{
prefix[0] = mostSignificantBit;
prefix[1] = leastSignificantBit;
}
std::vector<uint8_t> result = {prefix[0], prefix[1]};
auto data = to_bytevc(manufacturerData.Data());
result.insert(result.end(), data.begin(), data.end());
return result;
}
catch (const std::exception &e)
{
std::cerr << "Error in parsing manufacturer data for device " << deviceId << ": " << e.what() << std::endl;
}
catch (...)
{
std::cout << "Error in parsing manufacturer data: " << deviceId << std::endl;
return std::vector<uint8_t>();
std::cerr << "Unknown error occurred in parsing manufacturer data for device " << deviceId << std::endl;
}
return {};
}
winrt::fire_and_forget UniversalBlePlugin::InitializeAsync()
@@ -676,18 +692,19 @@ namespace universal_ble
auto universalScanResult = UniversalBleScanResult(deviceId);
std::string name = winrt::to_string(args.Advertisement().LocalName());
// Use CompleteName from dataType if localName is empty
if (name.empty())
auto dataSection = args.Advertisement().DataSections();
for (auto &&data : dataSection)
{
auto dataSection = args.Advertisement().DataSections();
for (auto &&data : dataSection)
auto dataBytes = to_bytevc(data.Data());
// Use CompleteName from dataType if localName is empty
if (name.empty() && data.DataType() == static_cast<uint8_t>(AdvertisementSectionType::CompleteLocalName))
{
auto dataBytes = to_bytevc(data.Data());
if (data.DataType() == 0x09)
{
name = std::string(dataBytes.begin(), dataBytes.end());
break;
}
name = std::string(dataBytes.begin(), dataBytes.end());
}
// Use ShortenedLocalName from dataType if localName is empty
else if (name.empty() && data.DataType() == static_cast<uint8_t>(AdvertisementSectionType::ShortenedLocalName))
{
name = std::string(dataBytes.begin(), dataBytes.end());
}
}