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\n", cnt++); } int sayhello_to(char *name) { static int cnt = 0; fprintf(stderr, "say hello to %s : %d\n", name, cnt++); return cnt; } void saygoodbye(void) { static int cnt = 0; fprintf(stderr, "say goodbye : %d\n", cnt++); } int saygoodbye_to(char *name) { static int cnt = 0; fprintf(stderr, "say goodbye to %s : %d\n", 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] = '\0'; /* 处理 */ i = sayhello_to(name); /* 把结果放入reply */ bio_put_uint32(reply, i); break; default: fprintf(stderr, "unknown code %d\n", 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] = '\0'; /* 处理 */ i = saygoodbye_to(name); /* 把结果放入reply */ bio_put_uint32(reply, i); break; default: fprintf(stderr, "unknown code %d\n", 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\n"); return -1; } /* add service */ ret = svcmgr_publish(bs, svcmgr, "hello", hello_service_handler); //注册 if (ret) { fprintf(stderr, "failed to publish hello service\n"); return -1; } ret = svcmgr_publish(bs, svcmgr, "goodbye", goodbye_service_handler); if (ret) { fprintf(stderr, "failed to publish goodbye service\n"); } #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:\n"); fprintf(stderr, "%s <hello|goodbye>\n", argv[0]); fprintf(stderr, "%s <hello|goodbye> <name>\n", argv[0]); return -1; } bs = binder_open(128*1024); //打开Binder驱动设备 if (!bs) { fprintf(stderr, "failed to open binder driver\n"); return -1; } g_bs = bs; /* get service */ handle = svcmgr_lookup(bs, svcmgr, "goodbye"); //查找获取服务的引用 if (!handle) { fprintf(stderr, "failed to get goodbye service\n"); return -1; } g_goodbye_handle = handle; fprintf(stderr, "Handle for goodbye service = %d\n", g_goodbye_handle); handle = svcmgr_lookup(bs, svcmgr, "hello"); if (!handle) { fprintf(stderr, "failed to get hello service\n"); return -1; } g_hello_handle = handle; fprintf(stderr, "Handle for hello service = %d\n", 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\n", 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\n", ret); } } binder_release(bs, handle); //释放binder_acquire(bs, handle); return 0; }

Android系统--Binder系统具体框架分析(一)补充的更多相关文章

  1. Android系统--Binder系统具体框架分析(二)Binder驱动情景分析

    Android系统--Binder系统具体框架分析(二)Binder驱动情景分析 1. Binder驱动情景分析 1.1 进程间通信三要素 源 目的:handle表示"服务",即向 ...

  2. Android系统--Binder系统具体框架分析(一)

    Binder系统具体框架分析(一) 一.Binder系统核心框架 1. IPC:Inter-Process Communication, 进程间通信 A进程将数据原原本本发送B进程,主要负责进程间数据 ...

  3. linux驱动基础系列--linux spi驱动框架分析(续)

    前言 这篇文章是对linux驱动基础系列--linux spi驱动框架分析的补充,主要是添加了最新的linux内核里设备树相关内容. spi设备树相关信息 如之前的文章里所述,控制器的device和s ...

  4. 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一

    作者:唐老师,华清远见嵌入式学院讲师. 1. Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor.LightsSensor. ProximitySensor.Temp ...

  5. 深入浅出 - Android系统移植与平台开发(八)- HAL Stub框架分析

    作者:唐老师,华清远见嵌入式学院讲师. 1. HAL Stub框架分析 HAL stub的框架比较简单,三个结构体.两个常量.一个函数,简称321架构,它的定义在:@hardware/libhardw ...

  6. Android Binder 系统学习笔记(一)Binder系统的基本使用方法

    1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的.RPC的一个应用场景如下: A进程想去打 ...

  7. 9.2 Binder系统_驱动情景分析_服务注册过程

    1. 几个重要结构体的引入给test_server添加一个goodbye服务, 由此引入以下概念: 进程间通信其实质也是需要三要素:源.目的.数据,源是自己,目的用handle表示:通讯的过程是源向实 ...

  8. Android系统--输入系统(五)输入系统框架

    Android系统--输入系统(五)输入系统框架 1. Android设备使用场景: 假设一个Android平板,APP功能.系统功能(开机关机.调节音量).外接设备功能(键盘.触摸屏.USB外接键盘 ...

  9. Android 核心分析 之六 IPC框架分析 Binder,Service,Service manager

    IPC框架分析 Binder,Service,Service manager 我首先从宏观的角度观察Binder,Service,Service Manager,并阐述各自的概念.从Linux的概念空 ...

随机推荐

  1. BestCoder Round #93 ABC

    A: 题目大意: 将数组划分成最少的段,每段的数两两不同. 题解:直接用一个map记录一个数是否出现过,贪心的每次取最多个数就好. B: 题目大意: 给出一个0-9组成的字符串,问能否删掉K个数字,使 ...

  2. python time与datetime.date/datetime模块

    https://docs.python.org/3/library/datetime.html 1.用于日期比较大小的方法 方法名 方法说明 用法 __eq__(…) 等于(x==y) x.__eq_ ...

  3. 【BZOJ2213】[Poi2011]Difference DP

    [BZOJ2213][Poi2011]Difference Description A word consisting of lower-case letters of the English alp ...

  4. 《从零开始学Swift》学习笔记(Day 22)——闭包那些事儿!

    原创文章,欢迎转载.转载请注明:关东升的博客    我给Swift 中的闭包一个定义:闭包是自包含的匿名函数代码块,可以作为表达式.函数参数和函数返回值,闭包表达式的运算结果是一种函数类型. Swif ...

  5. IIPP迷你项目(三)“Stopwatch: The Game”

    0 本周项目说明 这一次博客是Coursera的IIPP课程第三周迷你项目的实现,基础要求是做一个秒表,能start能stop能reset,更高的要求是在此秒表的基础上完成两个小游戏,但是鉴于第二个小 ...

  6. mysql中对应oracle中的to_char()和to_number()函数

    TO_CHAR(): CAST(123   AS   CHAR(3)) TO_NUMBER(): cast( '123 '   as   SIGNED   INTEGER)

  7. Machine Learning - week 2 - 编程练习

      3. % J = COMPUTECOST(X, y, theta) computes the cost of using theta as the % parameter for linear r ...

  8. HTML页面布局

    接下来的下面代码,只是给了一个大的前端编写布局,如果你已经是牛人了,就当没看到,如果是一些初学者,不妨拿去用用,里面也写了一些常用的css样式,现在虽然有很多牛逼的前段框架,用起来也非常得心应手,但是 ...

  9. Python3.6全栈开发实例[018]

    18.车牌区域划分, 现给出以下车牌.根据车牌的信息, 分析出各省的车牌持有量.(升级题) result = {} for car in cars: location = locals[car[0]] ...

  10. hdu 2112 HDU Today(map与dijkstra的结合使用)

    HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...