简体   繁体   中英

bitwise operator use in C++/WinRT CharacteristicProperties()

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.

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 2 | 8 is 10.

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, eg

auto const mask = r | w;
if ((p & mask) != 0) { ... }

I saw a post on CodeProject that helped me see the logic in the bitwise operators. I was thinking in terms of the C++ && || logic but the CodeProject post had this

The CodeProject table doesn't copy and paste here but it showed:

A = 0011, B = 0101
A and B = 0001 (ie what is in both A and B)
A or B = 0111 (ie what is in both A or B)

I believe this was mentioned in so many words above but this simple table was what my brain needed to see the binary logic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM