Example #1
0
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{
    int r = 1;
    uint32_t *end = ptr + (size / 4);

    while (ptr < end) {
        uint32_t cmd = *ptr++;
#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,"  %08x %08x\n", ptr[0], ptr[1]);
#endif
            ptr += 2;
            break;
        case BR_TRANSACTION: {
            struct binder_txn *txn = (void *) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("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);
                binder_send_reply(bs, &reply, txn->data, res);
            }
            ptr += sizeof(*txn) / sizeof(uint32_t);
            break;
        }
        case BR_REPLY: {
            struct binder_txn *txn = (void*) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                LOGE("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) / sizeof(uint32_t));
            r = 0;
            break;
        }
        case BR_DEAD_BINDER: {
            struct binder_death *death = (void*) *ptr++;
            death->func(bs, death->ptr);
            break;
        }
        case BR_FAILED_REPLY:
            r = -1;
            break;
        case BR_DEAD_REPLY:
            r = -1;
            break;
        default:
            LOGE("parse: OOPS %d\n", cmd);
            return -1;
        }
    }

    return r;
}
Example #2
0
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)) {
        fprintf(stderr, "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);
        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)) {
        fprintf(stderr, "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:
      fprintf(stderr, "parse: OOPS %d\n", cmd);
      return -1;
    }
  }

  return r;
}
Example #3
0
/*
 * 解析从驱动读取上来的数据,如果bio != NULL,则同时将数据保存到bio中
 */
int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uint32_t *ptr, uint32_t size, binder_handler func)
{
    int r = 1;
    uint32_t *end = ptr + (size / 4);

    while (ptr < end) {
        uint32_t cmd = *ptr++;
#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,"  %08x %08x\n", ptr[0], ptr[1]);
#endif
            ptr += 2;
            break;
        case BR_TRANSACTION: {
			// binder_txn结构跟binder_transaction_data结构是一样的,直接拿来用即可
            struct binder_txn *txn = (void *) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_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;

				// 初始化reply对象内存为binder_io结构
                bio_init(&reply, rdata, sizeof(rdata), 4);
				// 将binder_transaction_data结构转换为binder_io结构
                bio_init_from_txn(&msg, txn);
				// 调用回调函数处理msg对象,并将结果保存到reply对象中
                res = func(bs, txn, &msg, &reply);
				// 释放txn->data缓存; 给驱动发送reply数据,这些数据
				// 根据res的不同会有所不同(res==0表示回调函数执行成功)
                binder_send_reply(bs, &reply, txn->data, res);
            }
            ptr += sizeof(*txn) / sizeof(uint32_t);
            break;
        }
        case BR_REPLY: {
            struct binder_txn *txn = (void*) ptr;
            if ((end - ptr) * sizeof(uint32_t) < sizeof(struct binder_txn)) {
                ALOGE("parse: reply too small!\n");
                return -1;
            }
            binder_dump_txn(txn);
            if (bio) {
				// 如果调用者希望拿到数据,就把数据写入bio对象
                bio_init_from_txn(bio, txn);
                bio = 0;
            } else {
                    /* todo FREE BUFFER */
            }
            ptr += (sizeof(*txn) / sizeof(uint32_t));
            r = 0;
            break;
        }
        case BR_DEAD_BINDER: {
            struct binder_death *death = (void*) *ptr++;
            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;
}