Connman之D-Bus构架(待续)

Connman之D-Bus构架(待续)

        connman与ofono都实现了D-Bus API。通过研究发现两者的构成形式以及实现都很相似(使用ls命令,哈哈:)。不过也进行了简单的代码阅读)。现在就connman为例进行说明。
        connamn代码中的gdbus.h为connman的D-BUS核心文件。其实现了connman D-Bus API的最基本的结构体:GDBusMethodTable、GDBusSignalTable、GDBusPropertyTable、GDBusSecurityTable。通过以上的结构体,connman实现了比如Manager和Service等接口的各种Method、Signal等。

D-Bus API机制的参数传递(待续)

        在了解详细函数之前,我们要研究d-bus的API机制是如何将参数传递到底层的函数中的。以connman为例,当然connman与普通的d-bus有细微区别,这里并不代表所有的d-bus机制。


Connman之Manager接口

        manager.c实现了Manager这个接口。其中利用GDBusMethodTable实现了很多Method,这里就ConnectService方法做说明。
static GDBusMethodTable manager_methods[] = {
                   ......
                { "ConnectService",    "a{sv}", "o",     connect_service, G_DBUS_METHOD_FLAG_ASYNC },  
                   ......
}
        这个结构体说明Manager接口的ConnectService方法的输入参数数组"a{sv}"的元素是一个键-值对。"{sv}"表示键类型是字符串,值类型是VARIANT。、输出为对象路径。实现的函数是connect_service,GDBusMethodFlags是G_DBUS_METHOD_FLAG_ASYNC。

connect_service
        1、关于connect_service这个函数,参数有DBusConnection、DBusMessage和void *data。返回值也是DBusMessage。
        2、进入函数之后,函数判断当前是不是session_mode,如果是的话,返回一个标记参数无效的消息。按照它的connamn_info看,session_mode使能后不允许进行直接访问。查看相关代码,发现没有使能session_mode。
        3、然后本函数就会调用__connman_service_create_and_connect(msg),按照这个函数的定义,它只对WIFI有效。
        4、对于上面函数返回的err参数进行处理,一个是在connman的log里打印消息,一个是返回标记错误的消息。

__connman_service_create_and_connect(msg)
        好,看完了上面的函数主体,我们再看看__connman_service_create_and_connect(msg)的细节,这个函数是定义在service.c中的。这个函数只有一个msg做为参数,返回一个int值。
        1->开始递归
        1、dbus_message_iter_init、dbus_message_iter_recurse初始化一个iter来读取msg的参数,然后取得该参数的值。
        2、使用dbus_message_iter_get_arg_type来检测得到的数值恕不是希望获得的(DBUS_TYPE_DICT_ENTRY)。一般在d-bus中使用以上三个函数获得msg中的参数值,并进行校验。
        3、通过dbus_message_iter_recurse和dbus_message_iter_get_basic以及 dbus_message_iter_next的组合获取字典类消息的当前需要的值。
        4、验证最后获得的参数是不是WIFI的信息。如果是WIFI的信息,则存储WIFI的SSID等。
        5、判断获得的WIFI的信息是否有效,不是WIFI的话,这个函数就直接返回参数无效的错误。
        2->从device_list列表中取得当前device,取得设备标示(ident),取得WIFI加密种类,将WIFI信息打包到group里,然后再将WIFI信息,类型和标示打包到name里,最后通过name中的ident得到service结构体。
        如果没有service,则从隐藏的WIFI中获得。
        3->最后是获得service后的处理。
        1、释放资源、判断服务是否有效、判断链接是否存在。
        2、将结构体service->network->device->reconnect设置成FALSE。
        3、__connman_device_disconnect
        4、 __connman_service_connect(service);这个函数就是和Service的connect接口调用的核心一样了。深入的请看“Service的connect接口”


Service的connect接口 (待续)





你可能感兴趣的:(manager,api,session,service,Signal,methods)