Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Bluetooth Low Energy Heart Game Example - reinterpret_cast?



  • Hello,

    in the bluetooth low energy heart game example provided by qt there is this piece of code:

    void DeviceHandler::updateHeartRateValue(const QLowEnergyCharacteristic &c, const QByteArray &value)
    {
        // ignore any other characteristic change -> shouldn't really happen though
        if (c.uuid() != QBluetoothUuid(QBluetoothUuid::HeartRateMeasurement))
            return;
    
        auto data = reinterpret_cast<const quint8 *>(value.constData());
        quint8 flags = *data;
    
        //Heart Rate
        int hrvalue = 0;
        if (flags & 0x1) // HR 16 bit? otherwise 8 bit
            hrvalue = static_cast<int>(qFromLittleEndian<quint16>(data[1]));
        else
            hrvalue = static_cast<int>(data[1]);
    
        addMeasurement(hrvalue);
    }
    
    

    So after the characteristics have changed (new values are available) this slot ist called. Can anyone explain to me, what this code exactly does? (Noobfriendly for a C++ beginner? :) What would be the output if I just would print the value without making this reinterpret_cast and so on

    Thank you!



  • Hi @TUStudi,

    QByteArray::constData() returns a const char* value, which should be converted to const unsigned char* or const quint8 * (which is the same) in this case to interpret the heart rate data correctly.

    Printing constData() without casting could truncate data displayed as a const char* is considered to be a string and first '\0' (0x00) will be interpreted as the end of the string in this case, which is not the case with an unsigned char* array.

    I'm not an expert of BLE but I guess const QByteArray &value is used as a generic container here and is interpreted (casted) differently according to the case.

    Hope it helps



  • Hi @TUStudi,

    QByteArray::constData() returns a const char* value, which should be converted to const unsigned char* or const quint8 * (which is the same) in this case to interpret the heart rate data correctly.

    Printing constData() without casting could truncate data displayed as a const char* is considered to be a string and first '\0' (0x00) will be interpreted as the end of the string in this case, which is not the case with an unsigned char* array.

    I'm not an expert of BLE but I guess const QByteArray &value is used as a generic container here and is interpreted (casted) differently according to the case.

    Hope it helps


  • Lifetime Qt Champion

    @Gojir4 is mostly right, but the null termination is not the problem.

    The problem is, that char is most often signed, so doing arithmetic oprations like bit shifting might lead to wrong results.

    Hence the cast to an unsigned array.

    Regards



  • Thank you both very much.