BlueZ Part 6: Understanding DBUS – Get and Set Property – (5)

Introduction:

In our previous post, we explored the DBUS standard interfaces, focusing on the Properties interface, which provides a structured way to interact with objects in a service. We demonstrated how to use the Get method to retrieve the Powered property of a Bluetooth adapter managed by BlueZ, the official Linux Bluetooth protocol stack. This allowed us to check the power state of the adapter, offering a practical example of querying object attributes through DBUS.

Today, we will expand our understanding of the Properties interface by examining the Set method, which enables the modification of object properties. Specifically, we will explore how to use this method to control the power state of the BlueZ adapter, allowing it to be toggled on or off. This guide will provide a clear and concise overview of the steps involved, offering insights into practical applications and best practices for managing Bluetooth adapter states through DBUS.

Jumping into code:

Unlike our previous post, we will now directly jump into the code sample as have clear understanding about DBUS type system and BlueZ when we explore the Get property.

#include <gio/gio.h>
#include <stdio.h>
#include <unistd.h>

#define BLUEZ_BUS_NAME "org.bluez"
#define ADAPTER_OBJECT_PATH "/org/bluez/hci0"
#define ADAPTER_INTERFACE "org.bluez.Adapter1"
#define PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties"
#define PROPERTY "Powered"

static void set_power_state(GDBusConnection *connection, gboolean state) {
    GError *error = NULL;
    GVariant *result;
    GVariant *value;

    /* Create the property value variant */
    value = g_variant_new_boolean(state);

    /* Call the Set method on the org.freedesktop.DBus.Properties interface */
    result = g_dbus_connection_call_sync(
            connection,
            BLUEZ_BUS_NAME,                 /* Bus name */
            ADAPTER_OBJECT_PATH,            /* Object path */
            PROPERTIES_INTERFACE,           /* Interface name */
            "Set",                          /* Method name */
            g_variant_new("(ssv)", ADAPTER_INTERFACE, PROPERTY, value), /* Parameters */
            NULL,                           /* Expected return type */
            G_DBUS_CALL_FLAGS_NONE,         /* Flags */
            -1,                             /* Timeout (use default) */
            NULL,                           /* Cancellable */
            &error                          /* Error */
            );

    if (error != NULL) {
        fprintf(stderr, "Error setting power state: %s\n", error->message);
        g_error_free(error);
    } else {
        printf("Set power state to %s\n", state ? "on" : "off");
    }

    if (result != NULL) {
        g_variant_unref(result);
    }
}

int main(void)
{
    GDBusConnection *connection;
    GError *error = NULL;

    connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
    if (error != NULL) {
        fprintf(stderr, "Error connecting to system bus: %s\n", error->message);
        g_error_free(error);
        return 1;
    }

    /* Turn off the adapter */
    set_power_state(connection, FALSE);

    sleep(3);

    /* Turn on the adapter */
    set_power_state(connection, TRUE);

    /* Clean up and exit */
    g_object_unref(connection);
    return 0;
}

In DBus, method signatures define the types and order of the arguments passed to a method. The Set method in the org.freedesktop.DBus.Properties interface uses the signature "ssv".

Breakdown of "ssv" Signature

  • s: Represents a string.
  • s: Represents another string.
  • v: Represents a variant type, which can encapsulate any other DBus data type.

Usage in the Set Method

The Set method is used to set a property on a DBus object. The method signature "ssv" indicates that the method takes three arguments:

  1. Interface Name (s): The first string is the name of the interface containing the property you want to set. This tells DBus which interface the property belongs to.
  2. Property Name (s): The second string is the name of the property you want to change. This identifies the specific property within the given interface.
  3. New Value (v): The variant type holds the new value you want to set for the property. Since the variant can encapsulate any DBus data type, it allows flexibility in the type of data that can be set as the property’s value.

Example: Setting the Powered Property in BlueZ

For BlueZ, the Bluetooth stack for Linux, the Powered property of the org.bluez.Adapter1 interface controls whether a Bluetooth adapter is turned on or off. Here’s how the Set method is used to change the Powered property:

  1. Interface Name (s): "org.bluez.Adapter1" — This is the DBus interface for the Bluetooth adapter.
  2. Property Name (s): "Powered" — This is the property that controls the power state of the adapter.
  3. New Value (v): GVariant* containing a gboolean — The new value is a boolean encapsulated in a variant. For example, g_variant_new_boolean(FALSE) to turn off the adapter, or g_variant_new_boolean(TRUE) to turn it on.

Conclusion:

Now that we’ve mastered controlling and reading properties with DBUS, we are excited to delve deeper into advanced topics. Next, we’ll explore the GetAll method and dive into complex properties like UUIDs in the adapter interface. We’ll also look at other DBUS standard interfaces and signaling mechanisms. Stay tuned for more insights and practical examples! And don’t miss out—our complete code samples are freely available at our GitHub.

Written by

1 Comment

  • BlueZ Part 7: Understanding DBUS – (6) – Linumiz August 12, 2024 at 6:32 am

    […] our previous post, we explored the DBUS Set property using the org.freedesktop.DBus.Properties interface to control […]

    Reply
  • Please Post Your Comments & Reviews

    Your email address will not be published. Required fields are marked *