From af0342feb7d42bbce7c44b845a9c1202ddb4fbf5 Mon Sep 17 00:00:00 2001 From: ioacademy-jikim Date: Thu, 14 Jun 2018 10:57:45 +0900 Subject: [PATCH] 3 --- 03_day.pptx | Bin 88216 -> 99269 bytes 03_day/binder_1/Android.bp | 15 +- 03_day/binder_1/my_client.c | 54 +++ 03_day/binder_1/my_server.c | 12 + 03_day/binder_2/Android.bp | 35 ++ 03_day/binder_2/bctest.c | 107 ++++++ 03_day/binder_2/binder.c | 656 ++++++++++++++++++++++++++++++++++++ 03_day/binder_2/binder.h | 73 ++++ 03_day/binder_2/my_client.c | 55 +++ 03_day/binder_2/my_server.c | 99 ++++++ 03_day/sp/.sp.cpp.swp | Bin 0 -> 16384 bytes 03_day/sp/a.out | Bin 0 -> 13416 bytes 03_day/sp/sp.cpp | 341 +++++++++++++++++++ 13 files changed, 1444 insertions(+), 3 deletions(-) create mode 100644 03_day/binder_1/my_client.c create mode 100644 03_day/binder_2/Android.bp create mode 100644 03_day/binder_2/bctest.c create mode 100644 03_day/binder_2/binder.c create mode 100644 03_day/binder_2/binder.h create mode 100644 03_day/binder_2/my_client.c create mode 100644 03_day/binder_2/my_server.c create mode 100644 03_day/sp/.sp.cpp.swp create mode 100644 03_day/sp/a.out create mode 100644 03_day/sp/sp.cpp diff --git a/03_day.pptx b/03_day.pptx index 9556bf33dfb34c44099507af5ea2881552c258c0..225393e31148ecdf0ab19512b00741f9db55b121 100644 GIT binary patch delta 20192 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 delta 10147 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 +#include +#include +#include + +#include "binder.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; +} + +int main(int argc, char **argv) +{ + struct binder_state *bs; + uint32_t svcmgr = BINDER_SERVICE_MANAGER; + uint32_t handle; + unsigned iodata[512/4]; + struct binder_io msg, reply; + + bs = binder_open("/dev/binder", 128*1024); + if (!bs) { + fprintf(stderr, "failed to open binder driver\n"); + return -1; + } + + handle = svcmgr_lookup(bs, svcmgr, argv[argc-1]); + fprintf(stderr,"lookup(%s) = %x\n", argv[argc-1], handle); + + bio_init(&msg, iodata, sizeof(iodata), 4); + + binder_call(bs, &msg, &reply, handle, 1); + return 0; +} diff --git a/03_day/binder_1/my_server.c b/03_day/binder_1/my_server.c index eecbae4..d69e16d 100644 --- a/03_day/binder_1/my_server.c +++ b/03_day/binder_1/my_server.c @@ -36,6 +36,17 @@ int my_handler(struct binder_state *bs, struct binder_io *reply) { printf("my_handler %p %p %p %p\n", bs, txn, msg, reply); + switch(txn->code) { + case 1: + printf("Server : LED_ON, %p\n", (void*)txn->target.ptr); + return 0; + + default: + printf("unknown code %d\n", txn->code); + return -1; + } + + bio_put_uint32(reply, 0); return 0; } @@ -53,6 +64,7 @@ int main(int argc, char **argv) return -1; } + printf("Server : &token = %p\n", &token ); svcmgr_publish(bs, svcmgr, argv[argc-1], &token); binder_loop(bs, my_handler); return 0; diff --git a/03_day/binder_2/Android.bp b/03_day/binder_2/Android.bp new file mode 100644 index 0000000..6b98eee --- /dev/null +++ b/03_day/binder_2/Android.bp @@ -0,0 +1,35 @@ +cc_defaults { + name: "my_flags_3", + + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + ], + product_variables: { + binder32bit: { + cflags: ["-DBINDER_IPC_32BIT=1"], + }, + }, + + shared_libs: ["liblog"], +} + +cc_binary { + name: "my_server_3", + defaults: ["my_flags_3"], + srcs: [ + "my_server.c", + "binder.c", + ], +} + +cc_binary { + name: "my_client_3", + defaults: ["my_flags_3"], + srcs: [ + "my_client.c", + "binder.c", + ], +} + diff --git a/03_day/binder_2/bctest.c b/03_day/binder_2/bctest.c new file mode 100644 index 0000000..354df67 --- /dev/null +++ b/03_day/binder_2/bctest.c @@ -0,0 +1,107 @@ +/* Copyright 2008 The Android Open Source Project + */ + +#include +#include +#include +#include + +#include "binder.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; +} + +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); + 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)) + return -1; + + status = bio_get_uint32(&reply); + + binder_done(bs, &msg, &reply); + + return status; +} + +unsigned token; + +int main(int argc, char **argv) +{ + struct binder_state *bs; + uint32_t svcmgr = BINDER_SERVICE_MANAGER; + uint32_t handle; + + bs = binder_open("/dev/binder", 128*1024); + if (!bs) { + fprintf(stderr, "failed to open binder driver\n"); + return -1; + } + + argc--; + argv++; + while (argc > 0) { + if (!strcmp(argv[0],"alt")) { + handle = svcmgr_lookup(bs, svcmgr, "alt_svc_mgr"); + if (!handle) { + fprintf(stderr,"cannot find alt_svc_mgr\n"); + return -1; + } + svcmgr = handle; + fprintf(stderr,"svcmgr is via %x\n", handle); + } else if (!strcmp(argv[0],"lookup")) { + if (argc < 2) { + fprintf(stderr,"argument required\n"); + return -1; + } + handle = svcmgr_lookup(bs, svcmgr, argv[1]); + fprintf(stderr,"lookup(%s) = %x\n", argv[1], handle); + argc--; + argv++; + } else if (!strcmp(argv[0],"publish")) { + if (argc < 2) { + fprintf(stderr,"argument required\n"); + return -1; + } + svcmgr_publish(bs, svcmgr, argv[1], &token); + argc--; + argv++; + } else { + fprintf(stderr,"unknown command %s\n", argv[0]); + return -1; + } + argc--; + argv++; + } + return 0; +} diff --git a/03_day/binder_2/binder.c b/03_day/binder_2/binder.c new file mode 100644 index 0000000..93a18fc --- /dev/null +++ b/03_day/binder_2/binder.c @@ -0,0 +1,656 @@ +/* Copyright 2008 The Android Open Source Project + */ + +#define LOG_TAG "Binder" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "binder.h" + +#define MAX_BIO_SIZE (1 << 30) + +#define TRACE 0 + +void bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn); + +#if TRACE +void hexdump(void *_data, size_t len) +{ + unsigned char *data = _data; + size_t count; + + for (count = 0; count < len; count++) { + if ((count & 15) == 0) + fprintf(stderr,"%04zu:", count); + fprintf(stderr," %02x %c", *data, + (*data < 32) || (*data > 126) ? '.' : *data); + data++; + if ((count & 15) == 15) + fprintf(stderr,"\n"); + } + if ((count & 15) != 0) + fprintf(stderr,"\n"); +} + +void binder_dump_txn(struct binder_transaction_data *txn) +{ + struct flat_binder_object *obj; + binder_size_t *offs = (binder_size_t *)(uintptr_t)txn->data.ptr.offsets; + size_t count = txn->offsets_size / sizeof(binder_size_t); + + fprintf(stderr," target %016"PRIx64" cookie %016"PRIx64" code %08x flags %08x\n", + (uint64_t)txn->target.ptr, (uint64_t)txn->cookie, txn->code, txn->flags); + fprintf(stderr," pid %8d uid %8d data %"PRIu64" offs %"PRIu64"\n", + txn->sender_pid, txn->sender_euid, (uint64_t)txn->data_size, (uint64_t)txn->offsets_size); + hexdump((void *)(uintptr_t)txn->data.ptr.buffer, txn->data_size); + while (count--) { + obj = (struct flat_binder_object *) (((char*)(uintptr_t)txn->data.ptr.buffer) + *offs++); + fprintf(stderr," - type %08x flags %08x ptr %016"PRIx64" cookie %016"PRIx64"\n", + obj->type, obj->flags, (uint64_t)obj->binder, (uint64_t)obj->cookie); + } +} + +#define NAME(n) case n: return #n +const char *cmd_name(uint32_t cmd) +{ + switch(cmd) { + NAME(BR_NOOP); + NAME(BR_TRANSACTION_COMPLETE); + NAME(BR_INCREFS); + NAME(BR_ACQUIRE); + NAME(BR_RELEASE); + NAME(BR_DECREFS); + NAME(BR_TRANSACTION); + NAME(BR_REPLY); + NAME(BR_FAILED_REPLY); + NAME(BR_DEAD_REPLY); + NAME(BR_DEAD_BINDER); + default: return "???"; + } +} +#else +#define hexdump(a,b) do{} while (0) +#define binder_dump_txn(txn) do{} while (0) +#endif + +#define BIO_F_SHARED 0x01 /* needs to be buffer freed */ +#define BIO_F_OVERFLOW 0x02 /* ran out of space */ +#define BIO_F_IOERROR 0x04 +#define BIO_F_MALLOCED 0x08 /* needs to be free()'d */ + +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; + struct binder_version vers; + + bs = malloc(sizeof(*bs)); + if (!bs) { + errno = ENOMEM; + return NULL; + } + + bs->fd = open(driver, O_RDWR | O_CLOEXEC); + if (bs->fd < 0) { + fprintf(stderr,"binder: cannot open %s (%s)\n", + driver, strerror(errno)); + goto fail_open; + } + + if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) || + (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) { + fprintf(stderr, + "binder: kernel driver version (%d) differs from user space version (%d)\n", + vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION); + goto fail_open; + } + + bs->mapsize = mapsize; + bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0); + if (bs->mapped == MAP_FAILED) { + fprintf(stderr,"binder: cannot map device (%s)\n", + strerror(errno)); + goto fail_map; + } + + return bs; + +fail_map: + close(bs->fd); +fail_open: + free(bs); + return NULL; +} + +void binder_close(struct binder_state *bs) +{ + munmap(bs->mapped, bs->mapsize); + close(bs->fd); + free(bs); +} + +int binder_become_context_manager(struct binder_state *bs) +{ + return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0); +} + +int binder_write(struct binder_state *bs, void *data, size_t len) +{ + struct binder_write_read bwr; + int res; + + 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; + res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); + if (res < 0) { + fprintf(stderr,"binder_write: ioctl failed (%s)\n", + strerror(errno)); + } + return res; +} + +void binder_free_buffer(struct binder_state *bs, + binder_uintptr_t buffer_to_free) +{ + struct { + uint32_t cmd_free; + binder_uintptr_t buffer; + } __attribute__((packed)) data; + data.cmd_free = BC_FREE_BUFFER; + data.buffer = buffer_to_free; + binder_write(bs, &data, sizeof(data)); +} + +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)); +} + +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) { + uint32_t cmd = *(uint32_t *) ptr; + ptr += sizeof(uint32_t); +#if TRACE + fprintf(stderr,"%s:\n", cmd_name(cmd)); +#endif + switch(cmd) { + case BR_NOOP: + break; + case BR_TRANSACTION_COMPLETE: + break; + case BR_INCREFS: + case BR_ACQUIRE: + case BR_RELEASE: + case BR_DECREFS: +#if TRACE + fprintf(stderr," %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *))); +#endif + ptr += sizeof(struct binder_ptr_cookie); + break; + case BR_TRANSACTION: { + 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); + 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; + } + case BR_REPLY: { + struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; + if ((end - ptr) < sizeof(*txn)) { + ALOGE("parse: reply too small!\n"); + return -1; + } + binder_dump_txn(txn); + if (bio) { + bio_init_from_txn(bio, txn); + bio = 0; + } else { + /* todo FREE BUFFER */ + } + ptr += sizeof(*txn); + r = 0; + break; + } + case BR_DEAD_BINDER: { + struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr; + ptr += sizeof(binder_uintptr_t); + death->func(bs, death->ptr); + break; + } + case BR_FAILED_REPLY: + r = -1; + break; + case BR_DEAD_REPLY: + r = -1; + break; + default: + ALOGE("parse: OOPS %d\n", cmd); + return -1; + } + } + + return r; +} + +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_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_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)); +} + +int binder_call(struct binder_state *bs, + struct binder_io *msg, struct binder_io *reply, + uint32_t target, uint32_t code) +{ + int res; + struct binder_write_read bwr; + struct { + uint32_t cmd; + struct binder_transaction_data txn; + } __attribute__((packed)) writebuf; + unsigned readbuf[32]; + + if (msg->flags & BIO_F_OVERFLOW) { + fprintf(stderr,"binder: txn buffer overflow\n"); + goto fail; + } + + 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; + + bwr.write_size = sizeof(writebuf); + bwr.write_consumed = 0; + bwr.write_buffer = (uintptr_t) &writebuf; + + hexdump(msg->data0, msg->data - msg->data0); + 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: ioctl failed (%s)\n", strerror(errno)); + goto fail; + } + + res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0); + if (res == 0) return 0; + if (res < 0) goto fail; + } + +fail: + memset(reply, 0, sizeof(*reply)); + reply->flags |= BIO_F_IOERROR; + return -1; +} + +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) { + ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno)); + break; + } + + res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); + if (res == 0) { + ALOGE("binder_loop: unexpected reply?!\n"); + break; + } + if (res < 0) { + ALOGE("binder_loop: io error %d %s\n", res, strerror(errno)); + break; + } + } +} + +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; +} + +void bio_init(struct binder_io *bio, void *data, + size_t maxdata, size_t maxoffs) +{ + size_t n = maxoffs * sizeof(size_t); + + if (n > maxdata) { + bio->flags = BIO_F_OVERFLOW; + bio->data_avail = 0; + bio->offs_avail = 0; + return; + } + + bio->data = bio->data0 = (char *) data + n; + bio->offs = bio->offs0 = data; + bio->data_avail = maxdata - n; + bio->offs_avail = maxoffs; + bio->flags = 0; +} + +static void *bio_alloc(struct binder_io *bio, size_t size) +{ + size = (size + 3) & (~3); + if (size > bio->data_avail) { + bio->flags |= BIO_F_OVERFLOW; + return NULL; + } else { + void *ptr = bio->data; + bio->data += size; + bio->data_avail -= size; + return ptr; + } +} + +void binder_done(struct binder_state *bs, + __unused 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; + } +} + +static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio) +{ + struct flat_binder_object *obj; + + obj = bio_alloc(bio, sizeof(*obj)); + + if (obj && bio->offs_avail) { + bio->offs_avail--; + *bio->offs++ = ((char*) obj) - ((char*) bio->data0); + return obj; + } + + bio->flags |= BIO_F_OVERFLOW; + return NULL; +} + +void bio_put_uint32(struct binder_io *bio, uint32_t n) +{ + uint32_t *ptr = bio_alloc(bio, sizeof(n)); + if (ptr) + *ptr = n; +} + +void bio_put_obj(struct binder_io *bio, void *ptr) +{ + struct flat_binder_object *obj; + + obj = bio_alloc_obj(bio); + if (!obj) + return; + + obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; + obj->type = BINDER_TYPE_BINDER; + obj->binder = (uintptr_t)ptr; + obj->cookie = 0; +} + +void bio_put_ref(struct binder_io *bio, uint32_t handle) +{ + struct flat_binder_object *obj; + + if (handle) + obj = bio_alloc_obj(bio); + else + obj = bio_alloc(bio, sizeof(*obj)); + + if (!obj) + return; + + obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; + obj->type = BINDER_TYPE_HANDLE; + obj->handle = handle; + obj->cookie = 0; +} + +void bio_put_string16(struct binder_io *bio, const uint16_t *str) +{ + size_t len; + uint16_t *ptr; + + if (!str) { + bio_put_uint32(bio, 0xffffffff); + return; + } + + len = 0; + while (str[len]) len++; + + if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { + bio_put_uint32(bio, 0xffffffff); + return; + } + + /* Note: The payload will carry 32bit size instead of size_t */ + bio_put_uint32(bio, (uint32_t) len); + len = (len + 1) * sizeof(uint16_t); + ptr = bio_alloc(bio, len); + if (ptr) + memcpy(ptr, str, len); +} + +void bio_put_string16_x(struct binder_io *bio, const char *_str) +{ + unsigned char *str = (unsigned char*) _str; + size_t len; + uint16_t *ptr; + + if (!str) { + bio_put_uint32(bio, 0xffffffff); + return; + } + + len = strlen(_str); + + if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) { + bio_put_uint32(bio, 0xffffffff); + return; + } + + /* Note: The payload will carry 32bit size instead of size_t */ + bio_put_uint32(bio, len); + ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t)); + if (!ptr) + return; + + while (*str) + *ptr++ = *str++; + *ptr++ = 0; +} + +static void *bio_get(struct binder_io *bio, size_t size) +{ + size = (size + 3) & (~3); + + if (bio->data_avail < size){ + bio->data_avail = 0; + bio->flags |= BIO_F_OVERFLOW; + return NULL; + } else { + void *ptr = bio->data; + bio->data += size; + bio->data_avail -= size; + return ptr; + } +} + +uint32_t bio_get_uint32(struct binder_io *bio) +{ + uint32_t *ptr = bio_get(bio, sizeof(*ptr)); + return ptr ? *ptr : 0; +} + +uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz) +{ + size_t len; + + /* Note: The payload will carry 32bit size instead of size_t */ + len = (size_t) bio_get_uint32(bio); + if (sz) + *sz = len; + return bio_get(bio, (len + 1) * sizeof(uint16_t)); +} + +static struct flat_binder_object *_bio_get_obj(struct binder_io *bio) +{ + size_t n; + size_t off = bio->data - bio->data0; + + /* TODO: be smarter about this? */ + for (n = 0; n < bio->offs_avail; n++) { + if (bio->offs[n] == off) + return bio_get(bio, sizeof(struct flat_binder_object)); + } + + bio->data_avail = 0; + bio->flags |= BIO_F_OVERFLOW; + return NULL; +} + +uint32_t bio_get_ref(struct binder_io *bio) +{ + struct flat_binder_object *obj; + + obj = _bio_get_obj(bio); + if (!obj) + return 0; + + if (obj->type == BINDER_TYPE_HANDLE) + return obj->handle; + + return 0; +} diff --git a/03_day/binder_2/binder.h b/03_day/binder_2/binder.h new file mode 100644 index 0000000..69be94f --- /dev/null +++ b/03_day/binder_2/binder.h @@ -0,0 +1,73 @@ +/* Copyright 2008 The Android Open Source Project + */ +#ifndef _BINDER_H_ +#define _BINDER_H_ +#include +#include +struct binder_state; +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; +}; +struct binder_death { + void (*func)(struct binder_state *bs, void *ptr); + void *ptr; +}; +/* the one magic handle */ +#define BINDER_SERVICE_MANAGER 0U +#define SVC_MGR_NAME "android.os.IServiceManager" +enum { + /* Must match definitions in IBinder.h and IServiceManager.h */ + PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'), + SVC_MGR_GET_SERVICE = 1, + SVC_MGR_CHECK_SERVICE, + SVC_MGR_ADD_SERVICE, + SVC_MGR_LIST_SERVICES, +}; +typedef int (*binder_handler)(struct binder_state *bs, + struct binder_transaction_data *txn, + struct binder_io *msg, + struct binder_io *reply); +struct binder_state *binder_open(const char* driver, size_t mapsize); +void binder_close(struct binder_state *bs); +/* initiate a blocking binder call + * - returns zero on success + */ +int binder_call(struct binder_state *bs, + struct binder_io *msg, struct binder_io *reply, + uint32_t target, uint32_t code); +/* release any state associate with the binder_io + * - call once any necessary data has been extracted from the + * binder_io after binder_call() returns + * - can safely be called even if binder_call() fails + */ +void binder_done(struct binder_state *bs, + struct binder_io *msg, struct binder_io *reply); +/* manipulate strong references */ +void binder_acquire(struct binder_state *bs, uint32_t target); +void binder_release(struct binder_state *bs, uint32_t target); +void binder_link_to_death(struct binder_state *bs, uint32_t target, struct binder_death *death); +void binder_loop(struct binder_state *bs, binder_handler func); +int binder_become_context_manager(struct binder_state *bs); +/* allocate a binder_io, providing a stack-allocated working + * buffer, size of the working buffer, and how many object + * offset entries to reserve from the buffer + */ +void bio_init(struct binder_io *bio, void *data, + size_t maxdata, size_t maxobjects); +void bio_put_obj(struct binder_io *bio, void *ptr); +void bio_put_ref(struct binder_io *bio, uint32_t handle); +void bio_put_uint32(struct binder_io *bio, uint32_t n); +void bio_put_string16(struct binder_io *bio, const uint16_t *str); +void bio_put_string16_x(struct binder_io *bio, const char *_str); +uint32_t bio_get_uint32(struct binder_io *bio); +uint16_t *bio_get_string16(struct binder_io *bio, size_t *sz); +uint32_t bio_get_ref(struct binder_io *bio); +#endif diff --git a/03_day/binder_2/my_client.c b/03_day/binder_2/my_client.c new file mode 100644 index 0000000..3cddbfe --- /dev/null +++ b/03_day/binder_2/my_client.c @@ -0,0 +1,55 @@ + +#include +#include +#include +#include + +#include "binder.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; +} + +int main(int argc, char **argv) +{ + struct binder_state *bs; + uint32_t svcmgr = BINDER_SERVICE_MANAGER; + uint32_t handle; + unsigned iodata[512/4]; + struct binder_io msg, reply; + + bs = binder_open("/dev/binder", 128*1024); + if (!bs) { + fprintf(stderr, "failed to open binder driver\n"); + return -1; + } + + handle = svcmgr_lookup(bs, svcmgr, argv[argc-1]); + fprintf(stderr,"lookup(%s) = %x\n", argv[argc-1], handle); + + bio_init(&msg, iodata, sizeof(iodata), 4); + + binder_call(bs, &msg, &reply, handle, 1); + binder_call(bs, &msg, &reply, handle, 2); + return 0; +} diff --git a/03_day/binder_2/my_server.c b/03_day/binder_2/my_server.c new file mode 100644 index 0000000..cf3f3d7 --- /dev/null +++ b/03_day/binder_2/my_server.c @@ -0,0 +1,99 @@ +/* Copyright 2008 The Android Open Source Project + */ + +#include +#include +#include +#include + +#include "binder.h" + +typedef struct +{ + void (*on)(void); + void (*off)(void); +} LED_INFO; + +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); + 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)) + return -1; + + status = bio_get_uint32(&reply); + + binder_done(bs, &msg, &reply); + + return status; +} + +int my_handler(struct binder_state *bs, + struct binder_transaction_data *txn, + struct binder_io *msg, + struct binder_io *reply) +{ + printf("my_handler %p %p %p %p\n", bs, txn, msg, reply); + LED_INFO *Led = (LED_INFO*)txn->target.ptr; + switch(txn->code) { + case 1: + { + Led->on(); + return 0; + } + case 2: + { + Led->off(); + return 0; + } + + default: + printf("unknown code %d\n", txn->code); + return -1; + } + + bio_put_uint32(reply, 0); + return 0; +} + +void ledOn(void) +{ + printf("Server : ledOn\n"); +} + +void ledOff(void) +{ + printf("Server : ledOff\n"); +} + +int main(int argc, char **argv) +{ + struct binder_state *bs; + uint32_t svcmgr = BINDER_SERVICE_MANAGER; + LED_INFO *Led; + + bs = binder_open("/dev/binder", 128*1024); + if (!bs) { + fprintf(stderr, "failed to open binder driver\n"); + return -1; + } + Led = (LED_INFO*)malloc( sizeof(LED_INFO) ); + Led->on = ledOn; + Led->off = ledOff; + + printf("Server : &token = %p\n", Led ); + svcmgr_publish(bs, svcmgr, argv[argc-1], Led); + binder_loop(bs, my_handler); + return 0; +} + + + diff --git a/03_day/sp/.sp.cpp.swp b/03_day/sp/.sp.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..776e94868e267c50e1f7cf732ddbe81bdb27435a GIT binary patch literal 16384 zcmeI&eQXnD9Ki7h1mRG`h!7K#c^e|#=Gwg=V7HZQAtqpW2@C{>K-YGx(zR!MW8lJ2 z0=|Gckr)U>AjTJr$RFTaK+y=s7sx_T5QI3y0ntGsMnpi3-{;zHUAMtTAV_=~KIwY* z+|#GO`#sOya}Q&VWV>2=R{L=67fJ%-VV3RDpl0TqGEi$IlGo;9Mc$ji;Ky858BRK5Rg zlP|9>b(D&LihzoMihzoMihzoMihzoMiokUl0n_L%7Si(WvDP1ty?0A`zajQH6nj6B zv_JMyy{QPO2&f3C2&f3C2&f3C2&f3C2&f3C2&f3C2>b^l;PzU}{$i(`;IsZ8pZ}ll zC&URH$6+$#3ro4OQ^;ij6^S3;TVP#^hPiIr3rB!XVHM&_!yh;Hr8V;R$@77u>cV~h6;>A3eNN*$rg#PGp%P4O1`~g&2xl*l-t4^%UYLzQ70Ag3VZmHCTqHQH==7FaxD{ z7~?S(V~~qMNJAf7=pn?PIE5xO;s@-)*Z36M@gA0A4vH}nF5HJa3_%Khp>H-o_R$@( zpC-LDO*6v&pjmE9ix^I4ZN#vpPYwYL;lJ!G$fw@9{C6I`JQT7eR>c8Mr?oNK z6e`nd+1R#FbZbkgb_-b>o6E$T6>kcAIR*ZpCs5_}=>-wf>krv0Tx=@Wv&A4^(CaT3 zv>@y=tHMD&n^w#A7-d;5tBLt~G(H8z#li*o=JcDsN+aN=5e2$A-|z+9l|H>hcU>$k2x;52U}LMaunN^$ zTbob0)^4HJWs=i^z1Mq&=C;Z_Bd68Jh*1zt#9R{5$dP@qc~g$c&93Gqv22^0Y;2XA zR-tP+WL>3%kOLRFQ{r+uD<}HOBV-SwSS^T;3s&U`K~JtcGt>I6 z=;&b8mRPvuJFf6;aC9)XWw*JrroHi-e11p##z#vSD>`#;oFnA?e=767Z04tO{vV3X zEq-NQe-cgDkG=Q|+p!TFuo5fqBI>Xhi?9#@6r%{aaNusF;Z6)dcXY#9=Kg1J5?|s~ z%*R|*A%I6Q1Cx=8fw;h2zX>PMh@Wr(`|%Av!aGOt~6*B4>*H_EslrwQLL3cPAUIh+y>2SLb4F4gfuMDk;``0Q6L8+B#b$VS$s+oKCd$;(4s fJ)<3;tJqpqt3@N3^6_N3__C4JIhxCMym0g{Ga+|C literal 0 HcmV?d00001 diff --git a/03_day/sp/a.out b/03_day/sp/a.out new file mode 100644 index 0000000000000000000000000000000000000000..7c513b67780875471cf0454026aae78aa75523b1 GIT binary patch literal 13416 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 literal 0 HcmV?d00001 diff --git a/03_day/sp/sp.cpp b/03_day/sp/sp.cpp new file mode 100644 index 0000000..e7dbdd3 --- /dev/null +++ b/03_day/sp/sp.cpp @@ -0,0 +1,341 @@ +#if 1 +#include + +class AAA +{ + int mRefs; + public: + AAA():mRefs(0) { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } + void incStrong() { + printf("AAA::incStrong() : mRefs=%d\n", ++mRefs); + } + void decStrong() + { + --mRefs; + printf("AAA::decStrong() : mRefs=%d\n", mRefs); + if( mRefs == 0 ) + delete this; + } +}; + +template < typename T > +class sp +{ + T *mPtr; + public: + sp( T *ptr):mPtr(ptr) { + printf("sp::sp(T)\n"); + mPtr->incStrong(); + } + sp( const sp &r ) : mPtr(r.mPtr) { + printf("sp::sp(sp)\n"); + mPtr->incStrong(); + } + + ~sp() { + printf("sp::~sp()\n"); + mPtr->decStrong(); + } + + T * operator->() + { + return mPtr; + } + T operator*() + { + return *mPtr; + } +}; + +int main() +{ + { + sp p1 = new AAA; + sp p2 = p1; + p1->foo(); + p2->foo(); + } + return 0; +} +#endif +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } +}; + +template < typename T > +class sp +{ + T *mPtr; + static int mRefs; + public: + sp( T *ptr):mPtr(ptr) { + mRefs=1; + printf("sp::sp(T), mRefs=%d\n", mRefs); + } + sp( const sp &r ) { + mRefs++; + printf("sp::sp(sp), mRefs=%d\n", mRefs); + } + + ~sp() { + printf("sp::~sp()\n"); + if( --mRefs == 0 ) + delete mPtr; + } + + T * operator->() + { + return mPtr; + } + T operator*() + { + return *mPtr; + } +}; + +template < typename T > +int sp::mRefs = 0; + +int main() +{ + { + sp p1 = new AAA; + sp p2 = p1; + p1->foo(); + p2->foo(); + } + return 0; +} +#endif +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } +}; + +template < typename T > +class sp +{ + T *mPtr; + public: + sp( T *ptr):mPtr(ptr) { printf("sp::sp()\n"); } + ~sp() { + printf("sp::~sp()\n"); + delete mPtr; + } + + T * operator->() + { + return mPtr; + } + T operator*() + { + return *mPtr; + } +}; + +int main() +{ + { + sp p1 = new AAA; + sp p2 = p1; + p1->foo(); + p2->foo(); + } + return 0; +} +#endif +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } +}; +class BBB +{ + public: + BBB() { printf("BBB::BBB()\n"); } + ~BBB() { printf("BBB::~BBB()\n"); } + void foo() { printf("BBB::foo()\n"); } +}; + +template < typename T > +class sp +{ + T *mPtr; + public: + sp( T *ptr):mPtr(ptr) { printf("sp::sp()\n"); } + ~sp() { + printf("sp::~sp()\n"); + delete mPtr; + } + + T * operator->() + { + return mPtr; + } + T operator*() + { + return *mPtr; + } +}; + +int main() +{ + { + sp pa = new AAA; + pa->foo(); + + sp pb = new BBB; + pb->foo(); + } + return 0; +} +#endif +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } +}; + +class sp +{ + AAA *mPtr; + public: + sp( AAA *ptr):mPtr(ptr) { printf("sp::sp()\n"); } + ~sp() { + printf("sp::~sp()\n"); + delete mPtr; + } + + AAA * operator->() + { + return mPtr; + } + AAA operator*() + { + return *mPtr; + } +}; + +int main() +{ + { + sp pa = new AAA; + pa->foo(); // pa.operator->()->foo(); + + (*pa).foo(); + } + return 0; +} +#endif +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } + void foo() { printf("AAA::foo()\n"); } +}; + +class sp +{ + AAA *mPtr; + public: + sp( AAA *ptr):mPtr(ptr) { printf("sp::sp()\n"); } + ~sp() { + printf("sp::~sp()\n"); + delete mPtr; + } +}; + +int main() +{ + { + //AAA* pa = new AAA; + //pa->foo(); + sp pa = new AAA; + pa->foo(); // pa.operator->()->foo(); + } + return 0; +} +#endif + +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } +}; + +int main() +{ + AAA *pa = new AAA; + //... + return 0; +} +#endif + +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } +}; + +int main() +{ + AAA *pa = new AAA; + delete pa; + //... + return 0; +} +#endif + +#if 0 +#include + +class AAA +{ + public: + AAA() { printf("AAA::AAA()\n"); } + ~AAA() { printf("AAA::~AAA()\n"); } +}; + +int main() +{ + AAA aaa; + return 0; +} +#endif