binder系统C程序编写

binder系统C程序编写

怎么写APP?
1. client
a. binder_open
bs = binder_open(128*1024);
b. 获得服务:handle
handle = svcmgr_lookup(bs, svcmgr, "hello");
c. 构造参数binder_io
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
d. 调用binder_call
/* 调用binder_call */
if (binder_call(g_bs, &msg, &reply, g_handle, HELLO_SVR_CMD_SAYHELLO))
return ;

e. 分析返回binder_io, 取出返回值
/* 从reply中解析出返回值 */
ret = bio_get_uint32(&reply);
2. server
a. binder_open
bs = binder_open(128*1024);
b. 注册服务
/* add service */
ret = svcmgr_publish(bs, svcmgr, "hello", (void *)123);
if (!ret) {
fprintf(stderr, "failed to publish hello service\n");
return -1;
}
c. ioct 读数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
d. 解析数据
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
binder_write_read
binder_transaction_data
{
code;
txn->data.ptr.buffer
}
e. 根据code,决定调用哪个函数,从binder_io取出参数
res = func(bs, txn, &msg, &reply);
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;
}
f. 把返回值转换为binder_io,发给client, 到client的d这一步骤
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);

test_client

sayhello("weidongshan")
构造binder_io
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
调用binder_call
struct binder_write_read bwr;
struct {
uint32_t cmd;
struct binder_transaction_data txn;
} __attribute__((packed)) writebuf;
unsigned readbuf[32];

构造 writebuf
writebuf.cmd = BC_TRANSACTION;
writebuf.txn.target.handle = target;
writebuf.txn.code = code;
writebuf.txn.flags = 0;
writebuf.txn.data_size = msg->data - msg->data0;
writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);
writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;
writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;
构造binder_write_read
bwr.write_size = sizeof(writebuf);
bwr.write_consumed = 0;
bwr.write_buffer = (uintptr_t) &writebuf;
调用ioctl
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
-------》
注意, 此时server端 通过ioctl读数据,得到binder_read_write
得到上述binder_read_write后,
解析数据
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);

struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
if ((end - ptr) < sizeof(*txn)) {
ALOGE("parse: txn too small!\n");
return -1;
}
binder_dump_txn(txn);
if (func) {
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;

bio_init(&reply, rdata, sizeof(rdata), 4);
bio_init_from_txn(&msg, txn);
执行服务端hello
res = func(bs, txn, &msg, &reply);
将结果返回给client端
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}

posted @ 2021-05-12 14:51  zhudaheng123  阅读(181)  评论(0)    收藏  举报