thesillywhat
thesillywhat

Reputation: 69

Create a Bluetooth le server responsible for sending and receiving data using QT le

I am trying to create a simple Qt ble application that will send and receive data. Basically a le chat server.

I am unable to find any existing QT example codes that will help me achieve the same. So I wanted to know how do I go about creating one.

If I am understanding Qt Ble properly then,

  1. I have to construct a QLowEnergyAdvertisingData object

  2. Set Discoverability

  3. Set local name
  4. Add a list of services

I am confused here. Which service do I use for a simple transmission and reception. Do I now have to create a service and then register the local device to it? And then follow the similar procedure to create a characteristic UUID.

I had created a simple Bluetooth le android application long back. And I remember that I would set up a service UUID on my client which was similar to the server and was able to communicate back and forth The code was basically set up like this public static String ServiceUUID = "11223344-5566-7788-99aa-bbccddeeff00";

Then I would connect to this service uuid and was able to communicate back and forth

Edit 1: So after doing some research. I wrote this code

int main(int argc, char *argv[])
{
    //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
    static const QLatin1String serviceUuid("11223344-5566-7788-99aa-bbccddeeff00");
    static const QLatin1String charUuid("11223344-5566-7788-99aa-bbccddeeff11");
    QCoreApplication app(argc, argv);
    //! [Advertising Data]
    QLowEnergyAdvertisingData advertisingData;
    advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
    advertisingData.setIncludePowerLevel(true);
    advertisingData.setLocalName("Test_server");
    advertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid::HeartRate);
    //! [Advertising Data]

    //! [Service Data]
QLowEnergyCharacteristicData charData,rxData;
charData.setUuid(QBluetoothUuid(serviceUuid));
charData.setValue(QByteArray(2, 0));
charData.setProperties(QLowEnergyCharacteristic::Notify);
const QLowEnergyDescriptorData clientConfig(QBluetoothUuid::CharacteristicUserDescription,QByteArray(2, 0));
charData.addDescriptor(clientConfig);

rxData.setUuid(QBluetoothUuid(serviceUuid));
rxData.setValue(QByteArray(2, 0));
rxData.setProperties(QLowEnergyCharacteristic::Write);
const QLowEnergyDescriptorData discriptor(QBluetoothUuid::CharacteristicUserDescription,QByteArray(2, 0));
charData.addDescriptor(discriptor);

QLowEnergyServiceData serviceData;
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(QBluetoothUuid(serviceUuid));
serviceData.addCharacteristic(charData);
serviceData.addCharacteristic(rxData);
    //! [Service Data]

    //! [Start Advertising]
    const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
    QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
    leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,advertisingData);
}

So now I can connect to the bluetooth with my app But It keeps giving me an error

qt.bluetooth: Using BlueZ kernel ATT interface
qt.bluetooth.bluez: sending error response; request: 16 handle: 8 code: 10
qt.bluetooth.bluez: sending error response; request: 8 handle: 1 code: 10
qt.bluetooth.bluez: sending error response; request: 8 handle: 7 code: 10
qt.bluetooth.bluez: void QBluetoothSocketPrivateBluez::_q_readNotify() 9 error: -1 "Connection reset by peer"

What am I missing ?

Upvotes: 2

Views: 1724

Answers (1)

Razorneck
Razorneck

Reputation: 65

I think you are missing some basic ble knowledge.

Basics:

Your phone app acts as a central device. The linux machine is the peripheral. On service can have different characteristics and a char can have different descriptors.

There are 4 basic setups for the communication:

  1. write to peripheral
  2. read from peripheral
  3. notify from peripheral (let peripheral notify central device without request from ceantral device.)
  4. indicate from peripheral (same as 3. but with ack from central device)

The heart rate game shows the notify setup.

Questions related:

In your project I would suggest creating a custom service with two characteristics which you can write to and read from. Notification requires the central to write certain char on the peripheral you can read up on that yourself.

Yes you can use custom Uuid. Just use different ones.

You need to define callbacks on write or on read to handle interactions with a central device. In Qt you can use QLowEnergyService::characteristicChangedas signal and a custom slot.

If you want to go further read Qt Doc on QLowEnergerController, QLowEnergyService, QLowEnergyCharacteristicand QLowEnergyDescriptor. The Qt docs are great.

Anyway I think you want this:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    //QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
    static const QLatin1String serviceUuid("11223344-5566-7788-99aa-bbccddeeff00");
    static const QLatin1String charWriteUuid("11223344-5566-7788-99aa-bbccddeeff11");
    static const QLatin1String charReadUuid("11223344-5566-7788-99aa-bbccddeeff22");
    QCoreApplication app(argc, argv);
    //! [Advertising Data]
    QLowEnergyAdvertisingData advertisingData;
    advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
    advertisingData.setIncludePowerLevel(true);
    advertisingData.setLocalName("Test_server");
    advertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid(serviceUuid));
    //! [Advertising Data]

    //! [Service Data]
    QLowEnergyCharacteristicData charData,rxData;
    charData.setUuid(QBluetoothUuid(charReadUuid));
    charData.setProperties(QLowEnergyCharacteristic::Read);

    rxData.setUuid(QBluetoothUuid(charWriteUuid));
    rxData.setProperties(QLowEnergyCharacteristic::Write);

    QLowEnergyServiceData serviceData;
    serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
    serviceData.setUuid(QBluetoothUuid(serviceUuid));
    serviceData.addCharacteristic(charData);
    serviceData.addCharacteristic(rxData);

    //! [Service Data]

    //! [Start Advertising]
    const QScopedPointer<QLowEnergyController> leController(QLowEnergyController::createPeripheral());
    QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
    leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,advertisingData);
}

Upvotes: 1

Related Questions