cbluezgdbus

GLIB D-BUS Bluetooth - How to get the file descriptor?


I am using BLUEZ and GLIB/D-BUS to connect 2 Raspberry Pi (also a laptop and a Raspberry Pi). So far I could make fair progress.

EDIT: on good advises from @ukBaz I am using a python client from my laptop, and my C code server on the Raspberry Pi.

On the "server", I can register the device with a custom service UUID and a Serial RFCOMM profile UUID, and wait for connection. Connecting with the python client works and I can see that there is a handler available (see after code below for debug output) I'm using this code (within a dbus loop, code simplified for readability):

static void new_connection(GDBusMethodInvocation *inv)
{
    g_log(LOG_SERVER, G_LOG_LEVEL_MESSAGE, "New connection.");

    GDBusMessage *msg = g_dbus_method_invocation_get_message(inv);

    // This prints the output below this code snippet
    gchar *content = g_dbus_message_print(msg, 2);
    g_log(LOG_SERVER, G_LOG_LEVEL_INFO, "Message is:\n%s", content);
    g_free(content);
    GVariant *params = g_dbus_method_invocation_get_parameters(inv);

    const char *object;
    GVariant *properties;
    gint32 *handle;
    g_variant_get(params, "(oha{sv})", &object, &handle, &properties);

    // Problem here, 'handle' is NULL
    g_log(LOG_SERVER, G_LOG_LEVEL_INFO, "Object is [%s]\nHandle is [%ls]", object, handle);
    GVariantIter iter;
    g_variant_iter_init(&iter, properties);
    display_properties(&iter);
}

Here is the output:

New connection.
Message is:
  Type:    method-call
  Flags:   none
  Version: 0
  Serial:  32
  Headers:
    path -> objectpath '/org/bluez/jscturret'
    interface -> 'org.bluez.Profile1'
    member -> 'NewConnection'
    destination -> ':1.18'
    sender -> ':1.11'
    signature -> signature 'oha{sv}'
    num-unix-fds -> uint32 1
  Body: (objectpath '/org/bluez/hci0/dev_00_AA_AA_AA_AA_AA', handle 0, @a{sv} {})
  UNIX File Descriptors:
    fd 7: dev=0:8,mode=0140777,ino=41101,uid=0,gid=0,rdev=0:0,size=0,atime=0,mtime=0,ctime=0

Object is [/org/bluez/hci0/dev_00_AA_AA_AA_AA_AA]
Handle is [(null)]

It shows that there is a file descriptor fd 7 but when I read the GVariant parameter I get NULL.

How can I access the file descriptor? My understanding is I need that to be able to read/write from/to the client.

I used https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt and https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt for reference and a few other posts here on SO. Also got a lot of info in https://www.linumiz.com/.

Current full code is available here: btservice


Solution

  • Oh! I am pretty sure you are supposed to send a pointer to an integer (not a pointer to a pointer to it).

    You can do

    gint32 handle; // instead of gint32 *handle;

    and it should work.

    This API has a very poor design (relying on variadic, with format specifiers... the reason why people dislike C).