Using C /WinRT, Bluetooth LE, VS2017, Win10
I have a characteristic in my Bluetooth LE device that is Readable and Writable.
When checking the properties of various characteristics of a service with something like:
if (characteristic.CharacteristicProperties() == GattCharacteristicProperties::Write)
{
std::wcout << "IsWriteable = true; ";
}
The Read/Write characteristic will not get hit with ::Write and will not get hit with ::Read. The docs say that
This enumeration supports a bitwise combination of its member values.
So I tried the AND & operator since this is Read AND Write
if (characteristic.CharacteristicProperties() == (GattCharacteristicProperties::Read & GattCharacteristicProperties::Write))
{
std::wcout << "IsReadWrite = true; ";
}
However, that did not get hit either. The enumerated value of Read is 2 and of Write is 8 and in Debug this characteristic property showed as "Read | Write (10)". So I used the OR | operator in the snippet above and that hit.
My question is, why would the ::Read not hit and the ::Write not hit but the ::Read OR ::Write hit and the ::Read AND ::Write not hit?
Just kinda curious since this doesn't make sense to me.
CodePudding user response:
That's not how bitwise logic operators work. When you say CharacteristicProperties() == (Read & Write)
, that doesn't mean must be equal to Read
AND Write
. What it means is to compare the value against the result of performing a bitwise AND on Read
and Write
. Those values are b0010
and b1000
(in binary notation), and the operation returns the value 0.
What you meant to implement was a check whether both bits are set. That is done by performing a bitwise OR operation on the flags, and compare that result:
if (characteristic.CharacteristicProperties() == (GattCharacteristicProperties::Read | GattCharacteristicProperties::Write))
{
std::wcout << "IsReadWrite = true; ";
}
This verifies whether properties is exactly equal to the combination of Read
and Write
flags.
Although it is more common to check whether those flags are set (possibly in addition to other flags). Using p
, r
, and w
for the properties, read, and write flags, the following expression does that:
auto const mask = r | w;
if ((p & mask) == mask) { ... }
Another common operation is verifying whether any flags of a set of given flags are set, e.g.
auto const mask = r | w;
if ((p & mask) != 0) { ... }
CodePudding user response:
This is basic bit checking.
enum { Flag1 = 2, Flag2 = 8 };
To check a single bit: if (x & Flag1) ...
To check if any of two bits are set: if (x & (Flag1 | Flag2)) ...
To check if both bits are set: if ((x & (Flag1 | Flag2)) == (Flag1 | Flag2)) ...
The previous check can be rewritten as:
auto const bits = Flag1 | Flag2;
if ((x & bits) == bits)...
In your case, Flag1 & Flag2
is always 0 (2 & 8
is 0).
x == (Flag1 | Flag2)
only works if x
does not contain other bits (that are irrelevant flags). 2 | 8
is 10.