connman的agent实现原理简述
Charles Chan @ 2013-06-08 #Connman #WIFI @Program
Contents:
connman的处理方法是,要求客户端程序按着api-agent.txt的要求,自己实现一个dbus接口,挂在system bus上面。
实际上就是一种回调机制。当connman需要客户数据时,就会调用agent的接口去向用户索取。
下面总结一下通过gdbus和c语言实现与connman的交互。
这里主要是在进行wifi的连接认证工作。
其实就是实现了一个最简单版本的simple-agent。
主要做了两件事情:
1、注册Agent
2、当接受到connman来的请求时,做成密码信息发送回去
下面的代码用于实现目的一,也就是注册Agent。
这里是借助connman-manager.xml生成的gdbus接口。
首先,需要挂到connman的dbus上。注意,需要挂到system bus。
GDBusConnection * c;
NetConnmanManager *proxy;
GError *err = NULL;
c = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &err);
proxy = net_connman_manager_proxy_new_sync(c,
G_DBUS_PROXY_FLAGS_NONE,
"net.connman",
"/",
NULL,
&err);
然后就是注册,同样的借助connman-manager.xml生成的gdbus接口。
net_connman_manager_call_register_agent_sync(
proxy,
path, // something like "/net/connman/service/wifi_xxxxx_yyyyy_managed_psk"
NULL,
&error);
其次,起到关键作用的就是这个RequestInput函数了。
生成密码信息,并且返回给connman。
static gboolean on_handle_request_input (
NetConnmanAgent *object,
GDBusMethodInvocation *invocation,
const gchar *arg_unnamed_arg0,
GVariant *arg_unnamed_arg1,
gpointer user_data)
{
gchar * value[PASS_MAX];
scanf("%s", value);
GVariantBuilder * _builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
GVariant *_value = g_variant_new("s", value);
g_variant_builder_add (_builder, "{sv}", "Passphrase", _value);
GVariant *res = g_variant_new("a{sv}", _builder);
net_connman_agent_complete_request_input( object, invocation, res );
return TRUE;
}
最后附上xml文件和使用方法:
connman-agent.xml
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/test/Agent">
<interface name="net.connman.Agent">
<method name="ReportError">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="o" direction="in"/>
<arg type="s" direction="in"/>
</method>
<method name="RequestInput">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="o" direction="in"/>
<arg type="a{sv}" direction="in"/>
<arg type="a{sv}" direction="out"/>
</method>
<method name="RequestBrowser">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="o" direction="in"/>
<arg type="s" direction="in"/>
</method>
<method name="Cancel">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
<method name="Release">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method>
</interface>
</node>
connman-manager.xml
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/">
<interface name="net.connman.Manager">
<method name="RegisterAgent">
<arg name="path" type="o" direction="in"/>
</method>
<method name="UnregisterAgent">
<arg name="path" type="o" direction="in"/>
</method>
</interface>
</node>
使用方法:
gdbus-codegen --generate-c-code net_connman_agent connman-agent.xml
gdbus-codegen --generate-c-code net_connman_manager connman-manager.xml
追记:
可以通过下面命令查询任意dbus接口的详细信息:
dbus-send --session --type=method_call --print-reply --dest=com.xxx.yyy /com/xxx/yyy org.freedesktop.DBus.Introspectable.Introspect