zoukankan      html  css  js  c++  java
  • Android系统--Binder系统具体框架分析(一)补充

    Android系统--Binder系统具体框架分析(一)补充

    补充:对Binder驱动分析一的代码补充,添加saygoobye和saygoodbye_to服务

    test_server.h
    
    #ifndef _TEST_SERVER_H
    
    #define _TEST_SERVER_H
    
    #define HELLO_SVR_CMD_SAYHELLO 0
    
    #define HELLO_SVR_CMD_SAYHELLO_TO 1
    
    #define GOODBYE_SVR_CMD_SAYGOODBYE 0
    
    #define GOODBYE_SVR_CMD_SAYGOODBYE_TO 1
    
    #endif // _TEST_SERVER_H
    
    
    test_server.c
    
    /* Copyright 2008 The Android Open Source Project
    
     */
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <errno.h>
    
    #include <linux/types.h>
    
    #include<stdbool.h>
    
    #include <string.h>
    
    #include <private/android_filesystem_config.h>
    
    #include "binder.h"
    
    #include "test_server.h"
    
    int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
    
    {
    
        int status;
    
        unsigned iodata[512/4];
    
        struct binder_io msg, reply;
    
        bio_init(&msg, iodata, sizeof(iodata), 4);  //分配binder_io结构体空间
    
        bio_put_uint32(&msg, 0);  // strict mode header
    
        bio_put_string16_x(&msg, SVC_MGR_NAME);
    
        bio_put_string16_x(&msg, name);  
    
        bio_put_obj(&msg, ptr);  //构造结构体
    
        if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))  //添加注册Binder服务
    
            return -1;
    
        status = bio_get_uint32(&reply);  //获得返回值
    
        binder_done(bs, &msg, &reply);   //结束标志
    
        return status;
    
    }
    
    void sayhello(void)
    
    {
    
    	static int cnt = 0;
    
    	fprintf(stderr, "say hello : %d
    ", cnt++);
    
    }
    
    int sayhello_to(char *name)
    
    {
    
    	static int cnt = 0;
    
    	fprintf(stderr, "say hello to %s : %d
    ", name, cnt++);
    
    	return cnt;
    
    }
    
    void saygoodbye(void)
    
    {
    
    	static int cnt = 0;
    
    	fprintf(stderr, "say goodbye : %d
    ", cnt++);
    
    }
    
    int saygoodbye_to(char *name)
    
    {
    
    	static int cnt = 0;
    
    	fprintf(stderr, "say goodbye to %s : %d
    ", name, cnt++);
    
    	return cnt;
    
    }
    
    int hello_service_handler(struct binder_state *bs,
    
                       struct binder_transaction_data *txn,
    
                       struct binder_io *msg,
    
                       struct binder_io *reply)
    
    {
    
    	/* 根据txn->code知道要调用哪一个函数
    
    	 * 如果需要参数, 可以从msg取出
    
    	 * 如果要返回结果, 可以把结果放入reply
    
    	 */
    
    	/* sayhello
    
    	 * sayhello_to
    
    	 */
    
    	
    
        uint16_t *s;
    
    	char name[512];
    
        size_t len;
    
        uint32_t handle;
    
        uint32_t strict_policy;
    
    	int i;
    
        // Equivalent to Parcel::enforceInterface(), reading the RPC
    
        // header with the strict mode policy mask and the interface name.
    
        // Note that we ignore the strict_policy and don't propagate it
    
        // further (since we do no outbound RPCs anyway).
    
        strict_policy = bio_get_uint32(msg);
    
        //获得处理函数标志,并调用处理函数
    
        switch(txn->code) {
    
        case HELLO_SVR_CMD_SAYHELLO:
    
    		sayhello();
    
            return 0;
    
        case HELLO_SVR_CMD_SAYHELLO_TO:
    
    		/* 从msg里取出字符串 */
    
    		s = bio_get_string16(msg, &len);
    
    		if (s == NULL) {
    
    			return -1;
    
    		}
    
    		for (i = 0; i < len; i++)
    
    			name[i] = s[i];
    
    		name[i] = '';
    
    		/* 处理 */
    
    		i = sayhello_to(name);
    
    		/* 把结果放入reply */
    
    		bio_put_uint32(reply, i);
    
    		
    
            break;
    
        default:
    
            fprintf(stderr, "unknown code %d
    ", txn->code);
    
            return -1;
    
        }
    
        return 0;
    
    }
    
    int goodbye_service_handler(struct binder_state *bs,
    
                       struct binder_transaction_data *txn,
    
                       struct binder_io *msg,
    
                       struct binder_io *reply)
    
    {
    
    	/* 根据txn->code知道要调用哪一个函数
    
    	 * 如果需要参数, 可以从msg取出
    
    	 * 如果要返回结果, 可以把结果放入reply
    
    	 */
    
    	/* sayhello
    
    	 * sayhello_to
    
    	 */
    
    	
    
        uint16_t *s;
    
    	char name[512];
    
        size_t len;
    
        uint32_t handle;
    
        uint32_t strict_policy;
    
    	int i;
    
        // Equivalent to Parcel::enforceInterface(), reading the RPC
    
        // header with the strict mode policy mask and the interface name.
    
        // Note that we ignore the strict_policy and don't propagate it
    
        // further (since we do no outbound RPCs anyway).
    
        strict_policy = bio_get_uint32(msg);
    
        switch(txn->code) {
    
        case GOODBYE_SVR_CMD_SAYGOODBYE:
    
    		saygoodbye();
    
            return 0;
    
        case GOODBYE_SVR_CMD_SAYGOODBYE_TO:
    
    		/* 从msg里取出字符串 */
    
    		s = bio_get_string16(msg, &len);
    
    		if (s == NULL) {
    
    			return -1;
    
    		}
    
    		for (i = 0; i < len; i++)
    
    			name[i] = s[i];
    
    		name[i] = '';
    
    		/* 处理 */
    
    		i = saygoodbye_to(name);
    
    		/* 把结果放入reply */
    
    		bio_put_uint32(reply, i);
    
    		
    
            break;
    
        default:
    
            fprintf(stderr, "unknown code %d
    ", txn->code);
    
            return -1;
    
        }
    
        return 0;
    
    }
    
    int test_server_handler(struct binder_state *bs,
    
                       struct binder_transaction_data *txn,
    
                       struct binder_io *msg,
    
                       struct binder_io *reply)
    
    {
    
    	int (*handler)(struct binder_state *bs,
    
                       struct binder_transaction_data *txn,
    
                       struct binder_io *msg,
    
                       struct binder_io *reply);  //构造处理方法
    
    	handler = (int (*)(struct binder_state *bs,
    
                       struct binder_transaction_data *txn,
    
                       struct binder_io *msg,
    
                       struct binder_io *reply))txn->target.ptr;  //根据txn->target.ptr返回处理相应方法
    
    	
    
    	return handler(bs, txn, msg, reply);  //返回所调用的处理方法
    
    }
    
    int main(int argc, char **argv)
    
    {
    
        int fd;
    
        struct binder_state *bs;
    
        uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    
        uint32_t handle;
    
    	int ret;
    
        bs = binder_open(128*1024);  //打开Binder驱动设备
    
        if (!bs) {
    
            fprintf(stderr, "failed to open binder driver
    ");
    
            return -1;
    
        }
    
    	/* add service */
    
    	ret = svcmgr_publish(bs, svcmgr, "hello", hello_service_handler);  //注册
    
        if (ret) {
    
            fprintf(stderr, "failed to publish hello service
    ");
    
            return -1;
    
        }
    
    	ret = svcmgr_publish(bs, svcmgr, "goodbye", goodbye_service_handler);
    
        if (ret) {
    
            fprintf(stderr, "failed to publish goodbye service
    ");
    
        }
    
    #if 0
    
    	while (1)
    
    	{
    
    		/* read data */
    
    		/* parse data, and process */
    
    		/* reply */
    
    	}
    
    #endif
    
        binder_loop(bs, test_server_handler);  //从队列中取出响应的处理函数
    
        return 0;
    
    }
    
    
    server.c
    
    /* Copyright 2008 The Android Open Source Project
    
     */
    
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <errno.h>
    
    #include <linux/types.h>
    
    #include<stdbool.h>
    
    #include <string.h>
    
    #include <private/android_filesystem_config.h>
    
    #include "binder.h"
    
    #include "test_server.h"
    
    uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
    
    {
    
        uint32_t handle;
    
        unsigned iodata[512/4];
    
        struct binder_io msg, reply;
    
        bio_init(&msg, iodata, sizeof(iodata), 4);
    
        bio_put_uint32(&msg, 0);  // strict mode header
    
        bio_put_string16_x(&msg, SVC_MGR_NAME);
    
        bio_put_string16_x(&msg, name);
    
        if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
    
            return 0;
    
        handle = bio_get_ref(&reply);
    
        if (handle)
    
            binder_acquire(bs, handle);
    
        binder_done(bs, &msg, &reply);
    
        return handle;
    
    }
    
    struct binder_state *g_bs;
    
    uint32_t g_hello_handle;
    
    uint32_t g_goodbye_handle;
    
    void sayhello(void)
    
    {
    
        unsigned iodata[512/4];
    
        struct binder_io msg, reply;
    
    	/* 构造binder_io */
    
        bio_init(&msg, iodata, sizeof(iodata), 4);
    
        bio_put_uint32(&msg, 0);  // strict mode header
    
    	/* 放入参数 */
    
    	/* 调用binder_call */
    
        if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO))
    
            return ;
    
    	
    
    	/* 从reply中解析出返回值 */
    
        binder_done(g_bs, &msg, &reply);
    
    	
    
    }
    
    int sayhello_to(char *name)
    
    {
    
    	unsigned iodata[512/4];
    
    	struct binder_io msg, reply;
    
    	int ret;
    
    	/* 构造binder_io */
    
    	bio_init(&msg, iodata, sizeof(iodata), 4);
    
    	bio_put_uint32(&msg, 0);  // strict mode header
    
    	/* 放入参数 */
    
        bio_put_string16_x(&msg, name);
    
    	/* 调用binder_call */
    
    	if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO_TO))
    
    		return 0;
    
    	
    
    	/* 从reply中解析出返回值 */
    
    	ret = bio_get_uint32(&reply);
    
    	binder_done(g_bs, &msg, &reply);
    
    	return ret;
    
    	
    
    }
    
    void saygoodbye(void)
    
    {
    
        unsigned iodata[512/4];
    
        struct binder_io msg, reply;
    
    	/* 构造binder_io */
    
        bio_init(&msg, iodata, sizeof(iodata), 4);
    
        bio_put_uint32(&msg, 0);  // strict mode header
    
    	/* 放入参数 */
    
    	/* 调用binder_call */
    
        if (binder_call(g_bs, &msg, &reply, g_goodbye_handle, GOODBYE_SVR_CMD_SAYGOODBYE))
    
            return ;
    
    	
    
    	/* 从reply中解析出返回值 */
    
        binder_done(g_bs, &msg, &reply);
    
    	
    
    }
    
    int saygoodbye_to(char *name)
    
    {
    
    	unsigned iodata[512/4];
    
    	struct binder_io msg, reply;
    
    	int ret;
    
    	/* 构造binder_io */
    
    	bio_init(&msg, iodata, sizeof(iodata), 4);
    
    	bio_put_uint32(&msg, 0);  // strict mode header
    
    	/* 放入参数 */
    
        bio_put_string16_x(&msg, name);
    
    	/* 调用binder_call */
    
    	if (binder_call(g_bs, &msg, &reply, g_goodbye_handle, GOODBYE_SVR_CMD_SAYGOODBYE_TO))
    
    		return 0;
    
    	
    
    	/* 从reply中解析出返回值 */
    
    	ret = bio_get_uint32(&reply);
    
    	binder_done(g_bs, &msg, &reply);
    
    	return ret;
    
    	
    
    }
    
    /* ./test_client hello
    
     * ./test_client hello <name>
    
     */
    
    int main(int argc, char **argv)
    
    {
    
        int fd;
    
        struct binder_state *bs;
    
        uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    
        uint32_t handle;
    
    	int ret;
    
    	if (argc < 2){
    
            fprintf(stderr, "Usage:
    ");
    
            fprintf(stderr, "%s <hello|goodbye>
    ", argv[0]);
    
            fprintf(stderr, "%s <hello|goodbye> <name>
    ", argv[0]);
    
            return -1;
    
    	}
    
        bs = binder_open(128*1024);  //打开Binder驱动设备
    
        if (!bs) {
    
            fprintf(stderr, "failed to open binder driver
    ");
    
            return -1;
    
        }
    
    	g_bs = bs;
    
    	/* get service */
    
    	handle = svcmgr_lookup(bs, svcmgr, "goodbye");  //查找获取服务的引用
    
    	if (!handle) {
    
            fprintf(stderr, "failed to get goodbye service
    ");
    
            return -1;
    
    	}
    
    	g_goodbye_handle = handle;
    
    	fprintf(stderr, "Handle for goodbye service = %d
    ", g_goodbye_handle);
    
    	handle = svcmgr_lookup(bs, svcmgr, "hello");
    
    	if (!handle) {
    
            fprintf(stderr, "failed to get hello service
    ");
    
            return -1;
    
    	}
    
    	g_hello_handle = handle;
    
    	fprintf(stderr, "Handle for hello service = %d
    ", g_hello_handle);
    
    	/* send data to server */
    
    	if (!strcmp(argv[1], "hello"))
    
    	{
    
    		if (argc == 2) {
    
    			sayhello();
    
    		} else if (argc == 3) {
    
    			ret = sayhello_to(argv[2]);
    
    	        fprintf(stderr, "get ret of sayhello_to = %d
    ", ret);		
    
    		}
    
    	} else if (!strcmp(argv[1], "goodbye"))
    
    	{
    
    		if (argc == 2) {
    
    			saygoodbye();
    
    		} else if (argc == 3) {
    
    			ret = saygoodbye_to(argv[2]);
    
    	        fprintf(stderr, "get ret of sayhello_to = %d
    ", ret);		
    
    		}
    
    	}
    
    	binder_release(bs, handle);  //释放binder_acquire(bs, handle);
    
        return 0;
    
    }
    
    
  • 相关阅读:
    WCF使用net.tcp寄宿到IIS中
    (转)Dubbo 简单Dome搭建
    Linux压缩解压
    Linux关闭开启防火墙命令
    简单登录(jsp+servlet)
    UVa 10285 Longest Run on a Snowboard [DP]
    UVa 1218 Perfect Service [DFS+DP]
    第三届ACM山东省赛 Pick apples [贪心+动规]
    ZOJ 3326
    HDU 1029
  • 原文地址:https://www.cnblogs.com/lkq1220/p/6480375.html
Copyright © 2011-2022 走看看