在Android中,遠程過程調(diào)用是基于ONC RPC來實現(xiàn)的,在Android上層的接口為IBinder,在框架層面,其實現(xiàn)主要包括RPC路由器(RPC Router)、RPC服務(wù)器(RPC Server)和RPC管道等3部分。本文主要來講一下RPC路由器。
RPC路由器對服務(wù)器端和客戶端的通信提供了支持。在整個ONC RPC架構(gòu)上,ONC RPC主要由3部分構(gòu)成:客戶端、框架層、服務(wù)器端。其中框架層由RPC路由器和ONC RPC協(xié)議棧構(gòu)成,ONC RPC協(xié)議棧是基于ONC RPC協(xié)議的實現(xiàn),執(zhí)行接口描述語言的解析、自動產(chǎn)生RPC通信所需的框架代碼等工作。ONC RPC架構(gòu)如圖 1-1所示。

圖1-1 ONC RPC架構(gòu)
關(guān)于RPC路由器的實現(xiàn)主要分布在smd_rpcrouter.c、smd_rpcrouter_device.c、smd_rpcrouter_servers.c、smd_rpcrouter_clients.c等文件中。RPC路由器起著RPC服務(wù)器查詢、RPC服務(wù)器和RPC客戶端的注冊和銷毀,以及底層通信的封裝功能,類似于TCP協(xié)議。
在實際的實現(xiàn)中,RPC路由器和RPC服務(wù)器均是作為一個虛擬的字符型設(shè)備來存在的。
下面是RPC路由器的創(chuàng)建過程:
代碼1-1 RPC路由器的創(chuàng)建過程
int msm_rpcrouter_init_devices(void)
{
int rc;
int major;
msm_rpcrouter_class=class_create(THIS_MODULE, "oncrpc"); //創(chuàng)建設(shè)備節(jié)點
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");//作為字符型設(shè)備分配資源
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);//創(chuàng)建設(shè)備
if (IS_ERR(rpcrouter_device)) {
rc=-ENOMEM;
goto fail_unregister_cdev_region;
}
cdev_init(&rpcrouter_cdev, &rpcrouter_router_fops); //字符型設(shè)備初始化
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);//銷毀設(shè)備
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驅(qū)動為例,這是一個處理按鍵和LCD事件的驅(qū)動,在驅(qū)動創(chuàng)建時,會調(diào)用hs_rpc_init()函數(shù)進行RPC客戶端和RPC服務(wù)器的創(chuàng)建工作。
為了創(chuàng)建“hs”RPC客戶端,首先要完成RPC客戶端的注冊。在RPC客戶端向RPC路由器注冊的過程中,會首先調(diào)用msm_rpc_create_client()函數(shù)進行RPC客戶端的創(chuàng)建,隨后嘗試查詢RPC服務(wù)器進行鏈接。在完成這些工作后,會創(chuàng)建一個讀取數(shù)據(jù)的線程和一個回調(diào)線程。
在讀取數(shù)據(jù)的線程中,會循環(huán)執(zhí)行msm_rpc_read()函數(shù)進行操作,監(jiān)聽來自RPC服務(wù)器的響應(yīng)。
為了和RPC服務(wù)器進行通信,首先要調(diào)用msm_rpc_setup_req()函數(shù)創(chuàng)建一個rpc_request_hdr,然后通過msm_rpc_write()函數(shù)發(fā)送消息。在發(fā)送消息前,要首先調(diào)用rpcrouter_lookup_remote_endpoint()函數(shù)完成遠端服務(wù)器的查找工作,找到RPC服務(wù)器后,調(diào)用msm_rpc_write_pkt()函數(shù),通過smd_write()函數(shù)向共享內(nèi)存寫入數(shù)據(jù)。
為了創(chuàng)建“hs”RPC服務(wù)器,首先要調(diào)用msm_rpc_create_server()函數(shù)通過rpc_server_register()函數(shù)完成RPC服務(wù)器的創(chuàng)建和注冊工作。
創(chuàng)建服務(wù)器的過程為,首先通過rpcrouter_create_server()函數(shù)完成PRC服務(wù)器的創(chuàng)建,然后發(fā)送“RPCROUTER_CTRL_CMD_NEW_SERVER”命令通知RPC路由器。相關(guān)的路由器命令在process_control_msg()函數(shù)中進行處理。
當(dāng)銷毀RPC客戶端時,需要調(diào)用msm_rpc_unregister_client()函數(shù)完成本地端點的銷毀和回調(diào)函數(shù)的注銷。同時向RPC路由器發(fā)送“RPCROUTER_CTRL_CMD_REMOVE_ CLIENT”命令。