向 ConnMan 注册 RequestInput 函数的正确方法是什么?
What is the right way to register RequestInput function to ConnMan?
我正在实施 C 应用程序,它应该能够使用 ConnMan 通过 GDbus 连接到外部 Wi-Fi 保护接入点。到目前为止,我发现代理必须在“net.connman.Agent”接口上使用 RequestInput 回调进行注册,以便在连接到受保护的访问点期间提供密码。我正在这样注册代理:
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");
}
目前我没有在我的处理程序方法中处理任何输入,只是想看看它是否被调用。
但是当我在受保护的服务(在“扫描”之后获得)上调用“连接”时,我得到以下输出:
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}' 用于在不同文章/代码示例等中提到的输出
有没有人遇到过这样的错误?
如有任何建议和解决方案,我们将不胜感激。
谢谢。
自己找到了解决方案。看来签名确实是错误的,正确的是:
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>";
我正在实施 C 应用程序,它应该能够使用 ConnMan 通过 GDbus 连接到外部 Wi-Fi 保护接入点。到目前为止,我发现代理必须在“net.connman.Agent”接口上使用 RequestInput 回调进行注册,以便在连接到受保护的访问点期间提供密码。我正在这样注册代理:
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");
}
目前我没有在我的处理程序方法中处理任何输入,只是想看看它是否被调用。 但是当我在受保护的服务(在“扫描”之后获得)上调用“连接”时,我得到以下输出:
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}' 用于在不同文章/代码示例等中提到的输出
有没有人遇到过这样的错误?
如有任何建议和解决方案,我们将不胜感激。
谢谢。
自己找到了解决方案。看来签名确实是错误的,正确的是:
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>";