在Android中,远程过程调用是基于ONC RPC来实现的,在Android上层的接口为IBinder,在框架层面,其实现主要包括RPC路由器(RPC Router)、RPC服务器(RPC Server)和RPC管道等3部分。本文主要来讲一下RPC路由器。
RPC路由器对服务器端和客户端的通信提供了支持。在整个ONC RPC架构上,ONC RPC主要由3部分构成:客户端、框架层、服务器端。其中框架层由RPC路由器和ONC RPC协议栈构成,ONC RPC协议栈是基于ONC RPC协议的实现,执行接口描述语言的解析、自动产生RPC通信所需的框架代码等工作。ONC RPC架构如图 1-1所示。

图1-1 ONC RPC架构
关于RPC路由器的实现主要分布在smd_rpcrouter.c、smd_rpcrouter_device.c、smd_rpcrouter_servers.c、smd_rpcrouter_clients.c等文件中。RPC路由器起着RPC服务器查询、RPC服务器和RPC客户端的注册和销毁,以及底层通信的封装功能,类似于TCP协议。
在实际的实现中,RPC路由器和RPC服务器均是作为一个虚拟的字符型设备来存在的。
下面是RPC路由器的创建过程:
代码1-1 RPC路由器的创建过程
int msm_rpcrouter_init_devices(void)
{
int rc;
int major;
msm_rpcrouter_class=class_create(THIS_MODULE, "oncrpc"); //创建设备节点
if (IS_ERR(msm_rpcrouter_class)) {
rc=-ENOMEM;
printk(KERN_ERR"rpcrouter: failed to create oncrpc class\n");
goto fail;
}
rc=alloc_chrdev_region(& msm_rpcrouter_devno,0,RPCROUTER_MAX_REMOTE_SERVERS + 1, "oncrpc");//作为字符型设备分配资源
if (rc< 0) {
printk(KERN_ERR"rpcrouter: Failed to alloc chardev region (%d)\n", rc);
goto fail_destroy_class;
}
major=MAJOR(msm_rpcrouter_devno);
rpcrouter_device=device_create(msm_rpcrouter_class, NULL,msm_rpcrouter_devno, NULL, "%.8x:%d",0, 0);//创建设备
if (IS_ERR(rpcrouter_device)) {
rc=-ENOMEM;
goto fail_unregister_cdev_region;
}
cdev_init(&rpcrouter_cdev, &rpcrouter_router_fops); //字符型设备初始化
rpcrouter_cdev.owner=THIS_MODULE;
rc=cdev_add(&rpcrouter_cdev, msm_rpcrouter_devno, 1);
if (rc< 0)
goto fail_destroy_device;
return 0;
fail_destroy_device:
device_destroy(msm_rpcrouter_class, msm_rpcrouter_devno);//销毁设备
fail_unregister_cdev_region:
unregister_chrdev_region(msm_rpcrouter_devno,RPCROUTER_MAX_REMOTE_SERVERS + 1);//去注册
fail_destroy_class:
class_destroy(msm_rpcrouter_class);
fail:
return rc;
}
如图1-2所示为RPC客户端向RPC路由器进行注册和销毁的过程。

图1-2 RPC客户端注册和销毁过程
以msm-handset驱动为例,这是一个处理按键和LCD事件的驱动,在驱动创建时,会调用hs_rpc_init()函数进行RPC客户端和RPC服务器的创建工作。
为了创建“hs”RPC客户端,首先要完成RPC客户端的注册。在RPC客户端向RPC路由器注册的过程中,会首先调用msm_rpc_create_client()函数进行RPC客户端的创建,随后尝试查询RPC服务器进行链接。在完成这些工作后,会创建一个读取数据的线程和一个回调线程。
在读取数据的线程中,会循环执行msm_rpc_read()函数进行操作,监听来自RPC服务器的响应。
为了和RPC服务器进行通信,首先要调用msm_rpc_setup_req()函数创建一个rpc_request_hdr,然后通过msm_rpc_write()函数发送消息。在发送消息前,要首先调用rpcrouter_lookup_remote_endpoint()函数完成远端服务器的查找工作,找到RPC服务器后,调用msm_rpc_write_pkt()函数,通过smd_write()函数向共享内存写入数据。
为了创建“hs”RPC服务器,首先要调用msm_rpc_create_server()函数通过rpc_server_register()函数完成RPC服务器的创建和注册工作。
创建服务器的过程为,首先通过rpcrouter_create_server()函数完成PRC服务器的创建,然后发送“RPCROUTER_CTRL_CMD_NEW_SERVER”命令通知RPC路由器。相关的路由器命令在process_control_msg()函数中进行处理。
当销毁RPC客户端时,需要调用msm_rpc_unregister_client()函数完成本地端点的销毁和回调函数的注销。同时向RPC路由器发送“RPCROUTER_CTRL_CMD_REMOVE_ CLIENT”命令。