Android binder: ServiceManager server端 Android Bander设计与实现 - 设计篇: https://blog.csdn.net/universus/article/details/6211589 Android进程间通信(IPC)机制Binder简要介绍和学习计划

1. 学习文章:

Android Bander设计与实现 - 设计篇: 

https://blog.csdn.net/universus/article/details/6211589

红茶一杯话Binder:                                
https://my.oschina.net/youranhongcha/blog/149575

Android进程间通信(IPC)机制Binder简要介绍和学习计划

https://blog.csdn.net/luoshengyang/article/details/6618363/

2. ServiceManager server端实现
int main(int argc, char** argv)
{
    struct binder_state *bs;
    char *driver = "/dev/binder";

    bs = binder_open(driver, 128*1024);
    binder_become_context_manager(bs); /*ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0)*/

    binder_loop(bs, svcmgr_handler);
    return 0;
}

2.1. binder_open

/*初始化 binder_state: */
struct binder_state
{
    int fd;
    void *mapped;
    size_t mapsize;
};
struct binder_state *binder_open(const char* driver, size_t mapsize)
{
    struct binder_state *bs;

    bs = malloc(sizeof(*bs));
    bs->fd = open(driver, O_RDWR | O_CLOEXEC);
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);

    return bs;
}

2.2. binder loop

void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];
    /*通过binder_write: 写入数据:BC_ENTER_LOOPER
  *binder_write: 把数据转化为binder_write_read的格式和协议*/

    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(uint32_t));

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;
    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
/*循环读数据:并解析读到的结果*/
        ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
    }
}

2.2.1 向binder驱动文件写数据:binder write

/*向binder写/读数据都是通过结构体:binder_write_read:用读写大小区分读写:如果是写则把读大小设为0*/
struct binder_write_read {
binder_size_t write_size; /* bytes to write */
binder_size_t write_consumed; /* bytes consumed by driver */
binder_uintptr_t write_buffer;
binder_size_t read_size; /* bytes to read */
binder_size_t read_consumed; /* bytes consumed by driver */
binder_uintptr_t read_buffer;
};
向binder文件写数据:cmd:BINDER_WRITE_READ + binder_write_read数据类型,
binder_write_read数据结构的内容标示:是否为读写等;
write/read_size是否为0, 要写入/读到的数据在write/read_buffer里

int binder_write(struct binder_state *bs, void *data, size_t len)
{
    struct binder_write_read bwr;

    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

    return res;
}
/*通过ioctl: cmd + args的形式读写\控制等*/
cmd:
#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, __s32)
/*如果是读写则cmd: BINDER_WRITE_READ,后面的数据格式就是: struct binder_write_read*/

ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

2.2.2 从binder driver文件中读取数据

读到的内容格式是cmd + data(数据格式和cmd向对应):这里的cmd和操作binder driver文件的cmd不是一个层次.
如果来着driver的cmd是BR_TRANSACTION则后面跟随的数据格式是binder_transaction_data
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uintptr_t ptr, size_t size, binder_handler func)
{
    int r = 1;
    uintptr_t end = ptr + (uintptr_t) size;
    while (ptr < end) {
/*从binder driver文件对到数据格式:cmd+ 和cmd对应的数据格式:*/
        uint32_t cmd = *(uint32_t *) ptr;
        ptr += sizeof(uint32_t);

        switch(cmd) {
        case BR_TRANSACTION: {
            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
            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);
                res = func(bs, txn, &msg, &reply);
                if (txn->flags & TF_ONE_WAY) {
                    binder_free_buffer(bs, txn->data.ptr.buffer);
                } else {
                    binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
                }
            }
            ptr += sizeof(*txn);
            break;
        }
    }

    return r;
}

/*从binder driver file读到的cmd:*/
enum binder_driver_return_protocol {
BR_TRANSACTION = _IOR('r', 2, struct binder_transaction_data),
BR_REPLY = _IOR('r', 3, struct binder_transaction_data)
}
/*写入binder driver file的cmd:*/
enum binder_driver_command_protocol {
BC_TRANSACTION = _IOW('c', 0, struct binder_transaction_data),
BC_REPLY = _IOW('c', 1, struct binder_transaction_data)
}

cmd后面的数据格式和cmd相关, 以常见的BR_TRANSACTION为例:
struct binder_transaction_data {
/* The first two are only used for bcTRANSACTION and brTRANSACTION,
* identifying the target and contents of the transaction.
*/
union {
/* target descriptor of command transaction */
__u32 handle;
/* target descriptor of return transaction */
binder_uintptr_t ptr;
} target;
binder_uintptr_t cookie; /* target object cookie */
__u32 code; /* transaction command */

/* General information about the transaction. */
__u32        flags;
pid_t sender_pid;
uid_t sender_euid;
binder_size_t data_size; /* number of bytes of data */
binder_size_t offsets_size; /* number of bytes of offsets */


/* If this transaction is inline, the data immediately
* follows here; otherwise, it ends with a pointer to
* the data buffer.
*/
union {
struct {
/* transaction data */
binder_uintptr_t buffer;
/* offsets from buffer to flat_binder_object structs */
binder_uintptr_t offsets;
} ptr;
__u8 buf[8];
} data;
};

/*binder_transaction_data 和binder_io 的区别,为什么有引入binder_io?*/
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;
 /*return transaction: 检查brTransaction的Target是否为BINDER_SERVICE_MANAGER*/
    if (txn->target.ptr != BINDER_SERVICE_MANAGER)
        return -1;
    /*从传入的数据获得:strict_policy*/
    strict_policy = bio_get_uint32(msg);
    s = bio_get_string16(msg, &len);
    switch(txn->code) {
    case SVC_MGR_ADD_SERVICE:
/*从传入的数据获得:service name*/
        s = bio_get_string16(msg, &len);
/*flat_binder_object: representation of a Binder object for transfer between process
         *哪里形成了flat_binder_object
         */

        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
            return -1;
        break;
 }
    bio_put_uint32(reply, 0);
    return 0;
}

void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn)
{
    bio->data = bio->data0 = (char *)(intptr_t)txn->data.ptr.buffer;
    bio->offs = bio->offs0 = (binder_size_t *)(intptr_t)txn->data.ptr.offsets;
    bio->data_avail = txn->data_size;
    bio->offs_avail = txn->offsets_size / sizeof(size_t);
    bio->flags = BIO_F_SHARED;
}
struct binder_io
{
    char *data;            /* pointer to read/write from */
    binder_size_t *offs;   /* array of offsets */
    size_t data_avail;     /* bytes available in data buffer */
    size_t offs_avail;     /* entries available in offsets array */


    char *data0;           /* start of data buffer */
    binder_size_t *offs0;  /* start of offsets buffer */
    uint32_t flags;
    uint32_t unused;
};

int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
    struct svcinfo *si;

    if (!handle || (len == 0) || (len > 127))
        return -1;

    {
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        si->handle = handle;
        si->len = len;
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->allow_isolated = allow_isolated;
        si->next = svclist;
        svclist = si;
    }

    binder_acquire(bs, handle);
    return 0;
}
void binder_acquire(struct binder_state *bs, uint32_t target)
{
    uint32_t cmd[2];
    cmd[0] = BC_ACQUIRE;
    cmd[1] = target;
    binder_write(bs, cmd, sizeof(cmd));
}

server注册是通过是ServiceManager代理把server注册,这里有点绕。

猜你喜欢

转载自blog.csdn.net/u011279649/article/details/80907003