void binder_release(struct binder_state *bs, void *ptr) { uint32_t cmd[2]; cmd[0] = BC_RELEASE; cmd[1] = (uint32_t) ptr; binder_write(bs, cmd, sizeof(cmd)); }
void binder_loop(struct binder_state* bs, binder_handler func) { int res; struct binder_write_read bwr; uint32_t readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; readbuf[0] = BC_ENTER_LOOPER; binder_write(bs, readbuf, sizeof(uint32_t)); for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (uintptr_t) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0) { fprintf(stderr, "binder_loop: ioctl failed (%s)\n", strerror(errno)); break; } res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); if (res == 0) { fprintf(stderr, "binder_loop: unexpected reply?!\n"); break; } if (res < 0) { fprintf(stderr, "binder_loop: io error %d %s\n", res, strerror(errno)); break; } } }
void binder_send_reply(struct binder_state* bs, struct binder_io* reply, binder_uintptr_t buffer_to_free, int status) { struct { uint32_t cmd_free; binder_uintptr_t buffer; uint32_t cmd_reply; struct binder_transaction_data txn; } __attribute__((packed)) data; data.cmd_free = BC_FREE_BUFFER; data.buffer = buffer_to_free; data.cmd_reply = BC_REPLY; data.txn.target.ptr = 0; data.txn.cookie = 0; data.txn.code = 0; if (status) { data.txn.flags = TF_STATUS_CODE; data.txn.data_size = sizeof(int); data.txn.offsets_size = 0; data.txn.data.ptr.buffer = (uintptr_t)&status; data.txn.data.ptr.offsets = 0; } else { data.txn.flags = 0; data.txn.data_size = reply->data - reply->data0; data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0); data.txn.data.ptr.buffer = (uintptr_t)reply->data0; data.txn.data.ptr.offsets = (uintptr_t)reply->offs0; } binder_write(bs, &data, sizeof(data)); }
void binder_acquire(struct binder_state *bs, void *ptr) { uint32_t cmd[2]; cmd[0] = BC_ACQUIRE; cmd[1] = (uint32_t) ptr; binder_write(bs, cmd, sizeof(cmd)); }
void binder_release(struct binder_state *bs, uint32_t target) { uint32_t cmd[2]; cmd[0] = BC_RELEASE; cmd[1] = target; binder_write(bs, cmd, sizeof(cmd)); }
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)); }
void binder_send_reply(struct binder_state *bs, struct binder_io *reply, void *buffer_to_free, int status) { // 临时定义一个数据结构作为transaction data的实际内容, // 它是由两个cmd组成: 一个用于释放buffer,一个用于reply struct { uint32_t cmd_free; void *buffer; uint32_t cmd_reply; struct binder_txn txn; } __attribute__((packed)) data; data.cmd_free = BC_FREE_BUFFER; data.buffer = buffer_to_free; data.cmd_reply = BC_REPLY; data.txn.target = 0; data.txn.cookie = 0; data.txn.code = 0; if (status) { data.txn.flags = TF_STATUS_CODE; data.txn.data_size = sizeof(int); data.txn.offs_size = 0; data.txn.data = &status; data.txn.offs = 0; } else { data.txn.flags = 0; data.txn.data_size = reply->data - reply->data0; data.txn.offs_size = ((char*) reply->offs) - ((char*) reply->offs0); data.txn.data = reply->data0; data.txn.offs = reply->offs0; } binder_write(bs, &data, sizeof(data)); }
void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death) { uint32_t cmd[3]; cmd[0] = BC_REQUEST_DEATH_NOTIFICATION; cmd[1] = (uint32_t) ptr; cmd[2] = (uint32_t) death; binder_write(bs, cmd, sizeof(cmd)); }
void binder_link_to_death(struct binder_state* bs, uint32_t target, struct binder_death* death) { struct { uint32_t cmd; struct binder_handle_cookie payload; } __attribute__((packed)) data; data.cmd = BC_REQUEST_DEATH_NOTIFICATION; data.payload.handle = target; data.payload.cookie = (uintptr_t) death; binder_write(bs, &data, sizeof(data)); }
void binder_done(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply) { if (reply->flags & BIO_F_SHARED) { uint32_t cmd[2]; cmd[0] = BC_FREE_BUFFER; cmd[1] = (uint32_t) reply->data0; binder_write(bs, cmd, sizeof(cmd)); reply->flags = 0; } }
void binder_done(struct binder_state* bs, struct binder_io* msg, struct binder_io* reply) { struct { uint32_t cmd; uintptr_t buffer; } __attribute__((packed)) data; if (reply->flags & BIO_F_SHARED) { data.cmd = BC_FREE_BUFFER; data.buffer = (uintptr_t) reply->data0; binder_write(bs, &data, sizeof(data)); reply->flags = 0; } }
void binder_loop(struct binder_state *bs, binder_handler func) { int res; struct binder_write_read bwr; unsigned readbuf[32]; bwr.write_size = 0; bwr.write_consumed = 0; bwr.write_buffer = 0; readbuf[0] = BC_ENTER_LOOPER; printf("binder_write start 0x%x\n", BC_ENTER_LOOPER); binder_write(bs, readbuf, sizeof(unsigned)); printf("binder_write done\n"); for (;;) { bwr.read_size = sizeof(readbuf); bwr.read_consumed = 0; bwr.read_buffer = (unsigned long) readbuf; printf("ioctl BINDER_WRITE_READ start READ %ld, %ld, %ld\n", bwr.read_size, bwr.read_consumed, bwr.read_buffer); printf("ioctl BINDER_WRITE_READ start WRITE %ld, %ld, %ld\n", bwr.write_size, bwr.write_consumed, bwr.write_buffer); res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); printf("ioctl BINDER_WRITE_READ done res %d\n", res); if (res < 0) { LOGE("binder_loop: ioctl failed (%d)\n", errno); break; } res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func); if (res == 0) { LOGE("binder_loop: unexpected reply?!\n"); break; } if (res < 0) { LOGE("binder_loop: io error %d %d\n", res, errno); break; } } }