Deprecation notice: bluez, gnutls, qtconnectivity, qtsysteminfo, repomd-pattern-builder

I’d be happy to have a look for more documentation or a more complete example.

Well you win ;).

I think it would be definitely good to make some basic documentation about characteristics, device discovery, characteristics read/write/notifications.

2 Likes

Agreed, this would be useful. I’ll see if I can find anything good that’s already out there and we can at least collect together some good links.

If you find anything good during your investigations @orangecat, please share!

1 Like

I remember struggling with basic bluez5 dbus usage some time ago, and this was sadly among the best findings that actually helped me make some/any progress… Perhaps contributing directly to bluez5 documentation is also something to consider.

Also, there is https://github.com/piggz/qble

1 Like

I looked after the QtConnectivity and it looks like that the Bluez5 support was introduced in the Qt 5.4.0:
https://bugreports.qt.io/browse/QTBUG-32085

Are there any reason why the bluez5 based QtConnectivity could not remain?

1 Like

Mainly because maintaining it consumes resources. I appreciate you’ve wanted it properly supported for some time, and it will still be possible for someone else to maintain their own versions of the libraries in the future.

However, converting apps to Bluez or kf5bluezqt would be better in my view.

To add to the general discussion, the best reference docs for Bluez 5 in my experience are those in the bluez source tree. They’re terse, and lack useful examples, but all of the info is there. I agree that @piggz’s qble repo linked is a really great resource too (I’ve referred to it many times in the past).

@martonmiklos: your BLE Scanner app covers a lot of functionality, so I had a go at switching it from QtConnectivity to Bluez. Maybe it’s useful for others who are looking at making the switch. I included references to the docs and equivalent dbus-send calls to help add context to the code.

Mainly because maintaining it consumes resources.

What if we would do a PoC backporting and ship it without “warranty”? (Maybe through OBS.)

As mentioned before the BLE API was not allowed to the Harbour. Is there any care after ten years to have it in the Harbour?

Every (other) platform tries to offer the best in class API for all sort of things.
Are we sure that adding DBUS and Bluez as an API for Bluetooth is what could be called best API for interacting BLE devices?

I am not bitching for myself, I could live with the stuff mentioned above, but for the developers might come to the platform in the future…

What will we tell to somebody who want to interact BLE devices on SFOS?
Familiarise yourself with DBUS first and then with Bluez? It simply does not work out if you a newcomer.

your BLE Scanner app covers a lot of functionality

I would not call this my app, it is just a Qt Example wrapped into a Silica view.

I have an another BLE app for SFOS:

I almost started to port it to pure QML to being able to make it cross platform between SFOS/Android, but in this case this is not going to a valid task anymore.

1 Like

That’s what I was meaning when I suggested someone could maintain their own version, for example via Chum (assuming it fulfils the requirements after it’s removed from the Jolla repositories, but that’s a matter for the Chum maintainers).

Use of the Bluez 5 BLE API is allowed in harbour. For example, those changes I proposed to the BLE Scanner app allow it to pass harbour validation.

This is a totally valid concern, and I agree entirely with you raising it. In addition, we all put a lot of effort into learning and becoming expert in a particular API; switching is no small undertaking.

Nevertheless, I would say that the advice you give there is good advice, especially for Sailfish OS which makes heavy use of DBus, not just for Bluetooth but throughout. I’m less familiar with kf5bluezqt, but maybe that’s a better alternative for someone not wanting to get into DBus.

QtBluetooth isn’t a perfect solution either. For example, unlike Bluez 5 it doesn’t support BLE advertisements.

Agreed, unfortunately writing a cross platform Sailfish and Android app becomes less viable without QtConnectivity.

2 Likes

So I now took a stab at porting a QBluetooth application to kf5bluezqt. For the most part the API, especially the Qml part is really nice. But as soon as you need to go lower level, like open an rfcomm socket, you basically need to implement everything yourself. QBluetoothSocket is actually pretty nice for that, since it handles all the logic for you and you just need to give it the address. Reimplementing that is quite a pain.

1 Like

It also seems like kf5bluezqt is outdated by around 4 years, so all of the characteristics stuff is missing.

As qt5-qtsysteminfo will be removed I did some tests with nemo-qml-plugin-systemsettings as @flypig suggested here Sailfish Community News, 21st April, Sailfish SDK 3.9 - #10 by flypig.

I am under the impression that not all parameters in deviceInfo are set. I was looking for imei info (imeiNumbers, which looks undefined), but the same goes for something like wlanMacAddress.
The strange thing is that aboutSettings.wlanMacAddress works from systemsettings, but deviceInfo.wlanMacAddress is undefined at the same time.

deviceInfo.manufacturer is one of the values that is properly set btw.

What am I missing?

Kudos for taking the plunge, and thank you also for sharing your experiences. I was also very happy to see the constructive question you’ve raised for the next community meeting. I’ve not used kf5bluezqt myself so it’s hard for me to give any good advice about it, but I’ll do my best to try to find someone who can.

1 Like

I can only make a guess, but could it be that you’re not instantiating DeviceInfo? Using the following piece of code, the result wasn’t pretty, but it did show the correct IMEI numbers on my Xperia 10 II.

import QtQuick 2.0 
import Sailfish.Silica 1.0
import org.nemomobile.systemsettings 1.0

ApplicationWindow {
    property DeviceInfo deviceInfo: DeviceInfo {}
    initialPage: Component {
        Page {
            Label {
                text: "IMEI: " + deviceInfo.imeiNumbers
            }
        }
    }
}

I tried with imeiNumbers, wlanMacAddress and manufacturer and all gave correct values. If you share your code I’d be happy to explore it with you further.

Used your piece of code, but the result is the same as in my testcase (using Xperia XA2 Plus Dual sim):

  • IMEI: undefined
  • WLAN MAC: undefined
  • Manufacturer: Sony

As mentioned earlier aboutSettings.wlanMacAddress does return a valid WLAN MAC for me.

Same result as adekker

Only the following get displayed on my Sony Xperia 10 II;

    property DeviceInfo deviceInfo: DeviceInfo {}

Column {
    Label {
        text: "IMEI: " + deviceInfo.baseModel
    }
    Label {
        text: "IMEI: " + deviceInfo.designation
    }
    Label {
        text: "IMEI: " + deviceInfo.manufacturer
    }
    Label {
        text: "IMEI: " + deviceInfo.model
    }
    Label {
        text: "IMEI: " + deviceInfo.prettyName
    }
}
1 Like

Thanks @Edz and @adekker, for checking all of this. You’re absolutely right the changes to introduce imeiNumbers were added in version 0.7.0 of the nemo-qml-plugin-systemsettings library, which is ahead of the Vanha Rauma branch (Vanha Rauma is on version 0.5.90).

So I apologise for my earlier incorrect advice which missed this fact. My best suggestion right now is to look at the way it’s done there in the newer DeviceInfo code using QOfonoModem from qofono-qt5. Some of the properties are also available from the ssu-sysinfo library as an alternative.

2 Likes

Does the new bluez release support high resolution audio codecs and/ or multiple audio devices, e.g. playing audio to two Bluetooth speakers at the same time?

Not complete, but almost. . . @adekker @flypig

import QtQuick 2.6
import Sailfish.Silica 1.0
import org.nemomobile.systemsettings 1.0

Page {
    id: page

    allowedOrientations: Orientation.All

    property AboutSettings aboutSettings: AboutSettings {}
    property BatteryStatus batteryInfo: BatteryStatus {}
    property BatteryStatus batteryState: BatteryStatus {}
    property DeveloperModeSettings wlanIpAddress: DeveloperModeSettings {}
    property DeveloperModeSettings usbIpAddress: DeveloperModeSettings {}
    property DeveloperModeSettings workStatus: DeveloperModeSettings {}
    property DeviceInfo deviceInfo: DeviceInfo {}
    property DeviceInfo feature: DeviceInfo {}
    property DeviceInfo hasFeature: DeviceInfo {}
    property DeviceInfo wlanMacAddress: DeviceInfo {}
    property DeviceInfo deviceOwner: DeviceInfo {}
    property DeviceInfo hasHardwareKey: DeviceInfo {}
    property DisplaySettings displaySettings: DisplaySettings {}
    property LocationSettings locationEnabled: LocationSettings {}
    property NfcSettings nfcSettings: NfcSettings {}
    property USBSettings usbSettings: USBSettings {}
    property UserInfo userInfo: UserInfo {}
    property UserInfo setName: UserInfo {}
    property UserInfo userName: UserInfo {}    


    SilicaFlickable { anchors.fill: parent; contentHeight: column.height + Theme.paddingLarge
        Column { id: column; width: parent.width
            PageHeader { title: "About" }

            // OS
            SectionHeader { text: "OS" }
            DetailItem { label: "operatingSystem: ";     value: aboutSettings.baseOperatingSystemName }
            DetailItem { label: "adaptationVersion: ";  value: aboutSettings.adaptationVersion }
            DetailItem { label: "localisedOsName: ";    value: aboutSettings.localizedOperatingSystemName }
            DetailItem { label: "osVersion: ";          value: aboutSettings.softwareVersion }

            // DEVICE
            SectionHeader { text: "Device" }
            DetailItem { label: "model: ";              value: deviceInfo.model }
            DetailItem { label: "baseModel: ";          value: deviceInfo.baseModel }
            DetailItem { label: "designation: ";        value: deviceInfo.designation }
            DetailItem { label: "manufacturer: ";       value: deviceInfo.manufacturer }
            DetailItem { label: "prettyName: ";         value: deviceInfo.prettyName }

            // IMEI
            SectionHeader { text: "IMEI" }
            DetailItem { label: "imeiNumber: ";        value: aboutSettings.imei }

            // DISPLAY
            SectionHeader { text: "Display" }
            DetailItem { label: "adaptDimEnabled: ";    value: displaySettings.adaptiveDimmingEnabled }
            DetailItem { label: "ambLightSenseEnbld: "; value: displaySettings.ambientLightSensorEnabled }
            DetailItem { label: "autoBrightEnbld: ";    value: displaySettings.autoBrightnessEnabled }
            DetailItem { label: "blankTimeout: ";       value: displaySettings.blankTimeout }
            DetailItem { label: "brightness: ";         value: displaySettings.brightness }
            DetailItem { label: "dimTimeout: ";         value: displaySettings.dimTimeout }
            DetailItem { label: "flipGestureEnbld: ";   value: displaySettings.flipoverGestureEnabled }
            DetailItem { label: "inhibitMode: ";        value: displaySettings.inhibitMode }
            DetailItem { label: "lpmEnabled: ";         value: displaySettings.lowPowerModeEnabled }
            DetailItem { label: "lidSensorEnbld: ";     value: displaySettings.lidSensorEnabled }
            DetailItem { label: "pwrSaveEnbld: ";       value: displaySettings.powerSaveModeEnabled }
            DetailItem { label: "pwrSaveForced: ";      value: displaySettings.powerSaveModeForced }

            // USER
            SectionHeader { text: "User" }
            DetailItem { label: "username: ";           value: userInfo.username }
            DetailItem { label: "displayName: ";        value: userInfo.displayName }
            DetailItem { label: "alone: ";              value: userInfo.alone }
            DetailItem { label: "current: ";            value: userInfo.current }
            DetailItem { label: "type: ";               value: userInfo.type }

            // BATTERY
            SectionHeader { text: "Battery" }
            DetailItem { label: "chargePercentage: ";   value: batteryInfo.chargePercentage }
            DetailItem { label: "chargerStatus: ";      value: batteryInfo.chargerStatus }

            // NFC
            SectionHeader { text: "NFC" }
            DetailItem { label: "nfcSettingsAvailable: "; value: nfcSettings.available }
            DetailItem { label: "nfcSettingsEnabled: ";   value: nfcSettings.enabled }
            DetailItem { label: "nfcSettingsValid: ";     value: nfcSettings.valid }

            // LOCATION
            SectionHeader { text: "Location" }
            DetailItem { label: "locationEnabled: ";      value: locationEnabled.locationEnabled }
            DetailItem { label: "locationMode: ";         value: locationEnabled.locationMode }
            DetailItem { label: "locationProviders: ";    value: locationEnabled.locationProviders }

            // USB
            SectionHeader { text: "USB" }
            DetailItem { label: "available: ";            value: usbSettings.available }
            DetailItem { label: "usbIpAddress: ";         value: usbIpAddress.usbIpAddress }
            DetailItem { label: "currentMode: ";          value: usbSettings.currentMode }

            // WLAN
            SectionHeader { text: "WLAN" }
            DetailItem { label: "wlanIPaddress: ";        value: wlanIpAddress.wlanIpAddress }
        }
  }

High res codecs are just new profiles and don’t need bluez changes afaik. 2 speakers at a time needs a bluetooth 5.x capable device and support in the audio server. I think both need a newer pulseaudio or pipewire, but bluez.

My Bluetooth and OBD quest continues: Today I figured out how the bluez API works to connect to my OBD adapter as well as what protocol it speaks and how to open a socket to it. It seems like it isn’t actually using BLE characteristics, but instead just a profile, that I need to implement myself. In this case it uses the Serial Port Protocol, which just implements a Serial Port over Bluetooth.

To be able to connect to that you need to inherit the BluezQt::Profile class (if you are using kf5bluezqt) and register that profile with the agent using the manager. Of course UUID and ports have to match. Then your profile’s newConnection() function is called every time a BT device is connected to, which supports that profile. To this function a file descriptor is passed, which you can convert to a QLocalSocket, which basically provides the same functionality as the QtConnectivity QBluetooth socket.

With this I managed to connect to the dongle using my laptop and should be able to port OBDFish to it (once I have the SDK properly setup on my laptop since I am not at home). This means I don’t really need a kf5bluezqt update, although I do intend to PR one if I have the time after the meeting.

I made a minimal desktop example, which you can find here: https://github.com/deepbluev7/nicobd/tree/profile-example

Maybe someone will find that useful, the docs for the Bluez API don’t really help that much tbh, if you have no idea, what you should be doing. :smiley:

3 Likes