Как правильно зарегистрировать функцию RequestInput в ConnMan?

Я реализую приложение C, которое должно иметь возможность подключаться к внешним защищенным точкам доступа Wi-Fi с помощью ConnMan через GDbus. До сих пор я раскапывал, что Агент должен быть зарегистрирован с обратным вызовом RequestInput на интерфейсе net.connman.Agent, чтобы предоставить пароль при подключении к защищенной точке доступа. Я регистрирую агента так:

GDBusMessage* methodCallMessage = g_dbus_message_new_method_call("net.connman", "/", "net.connman.Manager", "RegisterAgent");

g_dbus_message_set_body(methodCallMessage, g_variant_new ("(o)", "/test/agent"));
g_dbus_connection_send_message(connection, methodCallMessage, G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &error);

Также я зарегистрировал интерфейс, подобный следующему:

guint registration_id = g_dbus_connection_register_object (connection,
                                                           "/test/agent",
                                                           introspection_data->interfaces[0],
                                                           &interface_vtable,
                                                           NULL,
                                                           NULL,
                                                           NULL);

где introspection_data генерируется из XML-кода, как показано ниже:

static const gchar introspection_xml[] =
"<node>"
"  <interface name='net.connman.Agent'>"
"    <method name='RequestInput'>"
"      <arg type='oa{sv}' name='service' direction='in'/>"
"      <arg type='a{sv}' name='fields' direction='out'/>"
"    </method>"
"  </interface>"
"</node>";
    
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);

и interface_vtable определяется следующим образом:

static const GDBusInterfaceVTable interface_vtable =
{
  handle_method_call,
  nullptr,
  nullptr
};

static void
handle_method_call (GDBusConnection       *connection,
                    const gchar           *sender,
                    const gchar           *object_path,
                    const gchar           *interface_name,
                    const gchar           *method_name,
                    GVariant              *parameters,
                    GDBusMethodInvocation *invocation,
                    gpointer               user_data)
{
    printf("Method called!\n");
}

В настоящее время я не обрабатываю никаких входных данных в своем методе обработчика, просто хочу увидеть, что он вызывается. Но когда я вызываю Connect на защищенных службах (полученных после сканирования), я получаю следующий вывод:

Call D-Bus method with reply: object = /net/connman/service/wifi_f8c091152c85_52696e6a692773206950686f6e65_managed_psk, interface = net.connman.Service, method name = Connect

(process:2929): GLib-CRITICAL **: 12:43:00.606: g_variant_type_checked_: assertion 'g_variant_type_string_is_valid (type_string)' failed

(process:2929): GLib-CRITICAL **: 12:43:00.606: g_variant_type_is_subtype_of: assertion 'g_variant_type_check (supertype)' failed

(process:2929): GLib-CRITICAL **: 12:43:00.606: g_variant_type_dup_string: assertion 'g_variant_type_check (type)' failed
Replied with error = 'GDBus.Error:net.connman.Error.InvalidArguments: Invalid arguments'

Насколько я понимаю, это может быть проблема с подписью RequestInput, но я видел только «oa {sv}» для ввода и «a {sv}» для вывода, упомянутых в разных статьях/примерах кода и т. д.

Кто-нибудь сталкивался с такой ошибкой раньше?

Любые предложения и решения будут оценены.

Спасибо.


person Vladyslav Pysarenko    schedule 22.06.2020    source источник


Ответы (1)


Сам нашел решение. Похоже, что подпись действительно была неправильной, и правильная следующая:

static const gchar introspection_xml[] =
  "<node>"
  "  <interface name='net.connman.Agent'>"
  "    <method name='RequestInput'>"
  "      <arg name='service' type='o' direction='in'/>"
  "      <arg name='fields' type='a{sv}' direction='in'/>"
  "      <arg name='fields' type='a{sv}' direction='out'/>"
  "    </method>"
  "  </interface>"
  "</node>";
person Vladyslav Pysarenko    schedule 23.06.2020