'DBus scanning for BLE device failing

I'm learning about DBus and Bluez and trying to get them to scan for BLE devices on Linux Mint using Lazarus Pascal. If I don't set a filter then the scan runs but doesn't find my device, but setting a filter gives me an error (connection disconnected). The code I'm trying first opens the System bus, sets the filter, starts scanning and tries to get the Managed Objects. It's on this final stage that it falls over, so I see:

Filter set
Started
Error waiting for reply: Connection was disconnected before a reply was received

from the following code:

<snip>

var
  err                      : DBusError;
  conn                     : PDBusConnection;
  msg, replymsg            : PDBusMessage;
  args, replyargs, subargs : DBusMessageIter;
  iterStru, iterDict,
  iterEntry, iterValue     : DBusMessageIter;
  dictKey, dictVal         : PChar;
  startTime                : qword;

<snip>

  { =========== Set discovery filter =========== }

  msg := dbus_message_new_method_call(
    'org.bluez',
    '/org/bluez/hci0',
    'org.bluez.Adapter1',
    'SetDiscoveryFilter');
  if msg = nil then begin
    writeLn('Could not construct message: ' + err.message);
    dbus_error_free(@err);
    exit;
  end;

  // add 'Transport': 'le' to dictionary argument
  dbus_message_iter_init_append(msg, @iterStru);
  dbus_message_iter_open_container(@iterStru, DBUS_TYPE_STRUCT, nil, @iterDict);

    dbus_message_iter_open_container(@iterDict, DBUS_TYPE_DICT_ENTRY, nil, @iterEntry);

      dictKey:='Transport';
      dbus_message_iter_append_basic(@iterEntry, DBUS_TYPE_STRING, @dictKey);

      dictVal:='le';
      dbus_message_iter_open_container(@iterEntry, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, @iterValue);
        dbus_message_iter_append_basic(@iterValue, DBUS_TYPE_STRING, @dictVal);
      dbus_message_iter_close_container(@iterEntry, @iterValue);

    dbus_message_iter_close_container(@iterDict, @iterEntry);

  dbus_message_iter_close_container(@iterStru, @iterDict);

  if dbus_connection_send(conn, msg, nil) = 0 then begin
    writeLn('Could not send filter');
    DBUSfinish;
    exit;
  end;

  writeLn('Filter set');

  { =========== Start scanning =========== }

  msg := dbus_message_new_method_call(
    'org.bluez',
    '/org/bluez/hci0',
    'org.bluez.Adapter1',
    'StartDiscovery');
  if msg = nil then begin
    writeLn('Could not construct message: ' + err.message);
    dbus_error_free(@err);
  end;

  if dbus_connection_send(conn, msg, nil) = 0 then begin
    writeLn('Could not send message');
    DBUSfinish;
    exit;
  end;

  writeLn('Started');

  { =========== Get Managed Objects =========== }

  msg := dbus_message_new_method_call(
   'org.bluez',
   '/',
   'org.freedesktop.DBus.ObjectManager',
   'GetManagedObjects');
  if msg = nil then begin
    writeLn('Could not construct message: ' + err.message);
    dbus_error_free(@err);
  end;

  startTime := GetTickcount64;

  while GetTickcount64-startTime < 15000 do begin

    replymsg := dbus_connection_send_with_reply_and_block(conn, msg, 1000, @err);
    if dbus_error_is_set(@err) <> 0 then begin
      writeLn('Error waiting for reply: ' + err.message);
      dbus_error_free(@err);
      break;
    end;

    if dbus_message_iter_init(replymsg, @replyargs) = 0 then
      writeln('No return value')
    else
    if dbus_message_iter_get_arg_type(@replyargs) <> DBUS_TYPE_ARRAY then
      writeln('Return value is not an array: ' + chr(dbus_message_iter_get_arg_type(@replyargs)))
    else begin
      writeln(stringofchar('-',50));
      ParseObjectMsg(@replyargs);
    end;

    sleep(1000);

  end;

There must be something wrong with the filter but I can't work out what!

PS. I'm pretty new to Linux too being a Windows programmer normally so the problem could be anywhere.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source