blob: 7fdd841edd439f603728a92bc0cfb1b76fa3c5ae [file] [log] [blame]
Mike Lockwood94afecf2012-10-24 10:45:23 -07001/* Copyright 2008 The Android Open Source Project
2 */
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <errno.h>
7#include <unistd.h>
8#include <fcntl.h>
9#include <sys/mman.h>
10
11#include "binder.h"
12
13#define MAX_BIO_SIZE (1 << 30)
14
15#define TRACE 0
16
17#define LOG_TAG "Binder"
18#include <cutils/log.h>
19
Serban Constantinescubcf38882014-01-10 13:56:27 +000020void bio_init_from_txn(struct binder_io *io, struct binder_transaction_data *txn);
Mike Lockwood94afecf2012-10-24 10:45:23 -070021
22#if TRACE
23void hexdump(void *_data, unsigned len)
24{
25 unsigned char *data = _data;
26 unsigned count;
27
28 for (count = 0; count < len; count++) {
29 if ((count & 15) == 0)
30 fprintf(stderr,"%04x:", count);
31 fprintf(stderr," %02x %c", *data,
32 (*data < 32) || (*data > 126) ? '.' : *data);
33 data++;
34 if ((count & 15) == 15)
35 fprintf(stderr,"\n");
36 }
37 if ((count & 15) != 0)
38 fprintf(stderr,"\n");
39}
40
Serban Constantinescubcf38882014-01-10 13:56:27 +000041void binder_dump_txn(struct binder_transaction_data *txn)
Mike Lockwood94afecf2012-10-24 10:45:23 -070042{
Serban Constantinescubcf38882014-01-10 13:56:27 +000043 struct flat_binder_object *obj;
44 unsigned *offs = txn->data.ptr.offsets;
45 unsigned count = txn->offsets_size / 4;
Mike Lockwood94afecf2012-10-24 10:45:23 -070046
47 fprintf(stderr," target %p cookie %p code %08x flags %08x\n",
Serban Constantinescubcf38882014-01-10 13:56:27 +000048 txn->target.ptr, txn->cookie, txn->code, txn->flags);
49 fprintf(stderr," pid %8d uid %8d data %zu offs %zu\n",
50 txn->sender_pid, txn->sender_euid, txn->data_size, txn->offsets_size);
51 hexdump(txn->data.ptr.buffer, txn->data_size);
Mike Lockwood94afecf2012-10-24 10:45:23 -070052 while (count--) {
Serban Constantinescubcf38882014-01-10 13:56:27 +000053 obj = (struct flat_binder_object *) (((char*) txn->data.ptr.buffer) + *offs++);
Mike Lockwood94afecf2012-10-24 10:45:23 -070054 fprintf(stderr," - type %08x flags %08x ptr %p cookie %p\n",
Serban Constantinescubcf38882014-01-10 13:56:27 +000055 obj->type, obj->flags, obj->binder, obj->cookie);
Mike Lockwood94afecf2012-10-24 10:45:23 -070056 }
57}
58
59#define NAME(n) case n: return #n
60const char *cmd_name(uint32_t cmd)
61{
62 switch(cmd) {
63 NAME(BR_NOOP);
64 NAME(BR_TRANSACTION_COMPLETE);
65 NAME(BR_INCREFS);
66 NAME(BR_ACQUIRE);
67 NAME(BR_RELEASE);
68 NAME(BR_DECREFS);
69 NAME(BR_TRANSACTION);
70 NAME(BR_REPLY);
71 NAME(BR_FAILED_REPLY);
72 NAME(BR_DEAD_REPLY);
73 NAME(BR_DEAD_BINDER);
74 default: return "???";
75 }
76}
77#else
78#define hexdump(a,b) do{} while (0)
79#define binder_dump_txn(txn) do{} while (0)
80#endif
81
82#define BIO_F_SHARED 0x01 /* needs to be buffer freed */
83#define BIO_F_OVERFLOW 0x02 /* ran out of space */
84#define BIO_F_IOERROR 0x04
85#define BIO_F_MALLOCED 0x08 /* needs to be free()'d */
86
87struct binder_state
88{
89 int fd;
90 void *mapped;
91 unsigned mapsize;
92};
93
94struct binder_state *binder_open(unsigned mapsize)
95{
96 struct binder_state *bs;
Serban Constantinescua44542c2014-01-30 15:16:45 +000097 struct binder_version vers;
Mike Lockwood94afecf2012-10-24 10:45:23 -070098
99 bs = malloc(sizeof(*bs));
100 if (!bs) {
101 errno = ENOMEM;
102 return 0;
103 }
104
105 bs->fd = open("/dev/binder", O_RDWR);
106 if (bs->fd < 0) {
107 fprintf(stderr,"binder: cannot open device (%s)\n",
108 strerror(errno));
109 goto fail_open;
110 }
111
Serban Constantinescua44542c2014-01-30 15:16:45 +0000112 if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
113 (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
114 fprintf(stderr, "binder: driver version differs from user space\n");
115 goto fail_open;
116 }
117
Mike Lockwood94afecf2012-10-24 10:45:23 -0700118 bs->mapsize = mapsize;
119 bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
120 if (bs->mapped == MAP_FAILED) {
121 fprintf(stderr,"binder: cannot map device (%s)\n",
122 strerror(errno));
123 goto fail_map;
124 }
125
Mike Lockwood94afecf2012-10-24 10:45:23 -0700126 return bs;
127
128fail_map:
129 close(bs->fd);
130fail_open:
131 free(bs);
132 return 0;
133}
134
135void binder_close(struct binder_state *bs)
136{
137 munmap(bs->mapped, bs->mapsize);
138 close(bs->fd);
139 free(bs);
140}
141
142int binder_become_context_manager(struct binder_state *bs)
143{
144 return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
145}
146
147int binder_write(struct binder_state *bs, void *data, unsigned len)
148{
149 struct binder_write_read bwr;
150 int res;
151 bwr.write_size = len;
152 bwr.write_consumed = 0;
153 bwr.write_buffer = (unsigned) data;
154 bwr.read_size = 0;
155 bwr.read_consumed = 0;
156 bwr.read_buffer = 0;
157 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
158 if (res < 0) {
159 fprintf(stderr,"binder_write: ioctl failed (%s)\n",
160 strerror(errno));
161 }
162 return res;
163}
164
165void binder_send_reply(struct binder_state *bs,
166 struct binder_io *reply,
167 void *buffer_to_free,
168 int status)
169{
170 struct {
171 uint32_t cmd_free;
172 void *buffer;
173 uint32_t cmd_reply;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000174 struct binder_transaction_data txn;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700175 } __attribute__((packed)) data;
176
177 data.cmd_free = BC_FREE_BUFFER;
178 data.buffer = buffer_to_free;
179 data.cmd_reply = BC_REPLY;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000180 data.txn.target.ptr = 0;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700181 data.txn.cookie = 0;
182 data.txn.code = 0;
183 if (status) {
184 data.txn.flags = TF_STATUS_CODE;
185 data.txn.data_size = sizeof(int);
Serban Constantinescubcf38882014-01-10 13:56:27 +0000186 data.txn.offsets_size = 0;
187 data.txn.data.ptr.buffer = &status;
188 data.txn.data.ptr.offsets = 0;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700189 } else {
190 data.txn.flags = 0;
191 data.txn.data_size = reply->data - reply->data0;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000192 data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
193 data.txn.data.ptr.buffer = reply->data0;
194 data.txn.data.ptr.offsets = reply->offs0;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700195 }
196 binder_write(bs, &data, sizeof(data));
197}
198
199int binder_parse(struct binder_state *bs, struct binder_io *bio,
200 uint32_t *ptr, uint32_t size, binder_handler func)
201{
202 int r = 1;
203 uint32_t *end = ptr + (size / 4);
204
205 while (ptr < end) {
206 uint32_t cmd = *ptr++;
207#if TRACE
208 fprintf(stderr,"%s:\n", cmd_name(cmd));
209#endif
210 switch(cmd) {
211 case BR_NOOP:
212 break;
213 case BR_TRANSACTION_COMPLETE:
214 break;
215 case BR_INCREFS:
216 case BR_ACQUIRE:
217 case BR_RELEASE:
218 case BR_DECREFS:
219#if TRACE
220 fprintf(stderr," %08x %08x\n", ptr[0], ptr[1]);
221#endif
222 ptr += 2;
223 break;
224 case BR_TRANSACTION: {
Serban Constantinescubcf38882014-01-10 13:56:27 +0000225 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
226 if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) {
Mike Lockwood94afecf2012-10-24 10:45:23 -0700227 ALOGE("parse: txn too small!\n");
228 return -1;
229 }
230 binder_dump_txn(txn);
231 if (func) {
232 unsigned rdata[256/4];
233 struct binder_io msg;
234 struct binder_io reply;
235 int res;
236
237 bio_init(&reply, rdata, sizeof(rdata), 4);
238 bio_init_from_txn(&msg, txn);
239 res = func(bs, txn, &msg, &reply);
Serban Constantinescubcf38882014-01-10 13:56:27 +0000240 binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
Mike Lockwood94afecf2012-10-24 10:45:23 -0700241 }
242 ptr += sizeof(*txn) / sizeof(uint32_t);
243 break;
244 }
245 case BR_REPLY: {
Serban Constantinescubcf38882014-01-10 13:56:27 +0000246 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
247 if ((end - ptr) * sizeof(uint32_t) < sizeof(*txn)) {
Mike Lockwood94afecf2012-10-24 10:45:23 -0700248 ALOGE("parse: reply too small!\n");
249 return -1;
250 }
251 binder_dump_txn(txn);
252 if (bio) {
253 bio_init_from_txn(bio, txn);
254 bio = 0;
255 } else {
256 /* todo FREE BUFFER */
257 }
258 ptr += (sizeof(*txn) / sizeof(uint32_t));
259 r = 0;
260 break;
261 }
262 case BR_DEAD_BINDER: {
263 struct binder_death *death = (void*) *ptr++;
264 death->func(bs, death->ptr);
265 break;
266 }
267 case BR_FAILED_REPLY:
268 r = -1;
269 break;
270 case BR_DEAD_REPLY:
271 r = -1;
272 break;
273 default:
274 ALOGE("parse: OOPS %d\n", cmd);
275 return -1;
276 }
277 }
278
279 return r;
280}
281
282void binder_acquire(struct binder_state *bs, void *ptr)
283{
284 uint32_t cmd[2];
285 cmd[0] = BC_ACQUIRE;
286 cmd[1] = (uint32_t) ptr;
287 binder_write(bs, cmd, sizeof(cmd));
288}
289
290void binder_release(struct binder_state *bs, void *ptr)
291{
292 uint32_t cmd[2];
293 cmd[0] = BC_RELEASE;
294 cmd[1] = (uint32_t) ptr;
295 binder_write(bs, cmd, sizeof(cmd));
296}
297
298void binder_link_to_death(struct binder_state *bs, void *ptr, struct binder_death *death)
299{
300 uint32_t cmd[3];
301 cmd[0] = BC_REQUEST_DEATH_NOTIFICATION;
302 cmd[1] = (uint32_t) ptr;
303 cmd[2] = (uint32_t) death;
304 binder_write(bs, cmd, sizeof(cmd));
305}
306
307
308int binder_call(struct binder_state *bs,
309 struct binder_io *msg, struct binder_io *reply,
310 void *target, uint32_t code)
311{
312 int res;
313 struct binder_write_read bwr;
314 struct {
315 uint32_t cmd;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000316 struct binder_transaction_data txn;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700317 } writebuf;
318 unsigned readbuf[32];
319
320 if (msg->flags & BIO_F_OVERFLOW) {
321 fprintf(stderr,"binder: txn buffer overflow\n");
322 goto fail;
323 }
324
325 writebuf.cmd = BC_TRANSACTION;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000326 writebuf.txn.target.handle = target;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700327 writebuf.txn.code = code;
328 writebuf.txn.flags = 0;
329 writebuf.txn.data_size = msg->data - msg->data0;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000330 writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);
331 writebuf.txn.data.ptr.buffer = msg->data0;
332 writebuf.txn.data.ptr.offsets = msg->offs0;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700333
334 bwr.write_size = sizeof(writebuf);
335 bwr.write_consumed = 0;
336 bwr.write_buffer = (unsigned) &writebuf;
337
338 hexdump(msg->data0, msg->data - msg->data0);
339 for (;;) {
340 bwr.read_size = sizeof(readbuf);
341 bwr.read_consumed = 0;
342 bwr.read_buffer = (unsigned) readbuf;
343
344 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
345
346 if (res < 0) {
347 fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
348 goto fail;
349 }
350
351 res = binder_parse(bs, reply, readbuf, bwr.read_consumed, 0);
352 if (res == 0) return 0;
353 if (res < 0) goto fail;
354 }
355
356fail:
357 memset(reply, 0, sizeof(*reply));
358 reply->flags |= BIO_F_IOERROR;
359 return -1;
360}
361
362void binder_loop(struct binder_state *bs, binder_handler func)
363{
364 int res;
365 struct binder_write_read bwr;
366 unsigned readbuf[32];
367
368 bwr.write_size = 0;
369 bwr.write_consumed = 0;
370 bwr.write_buffer = 0;
371
372 readbuf[0] = BC_ENTER_LOOPER;
373 binder_write(bs, readbuf, sizeof(unsigned));
374
375 for (;;) {
376 bwr.read_size = sizeof(readbuf);
377 bwr.read_consumed = 0;
378 bwr.read_buffer = (unsigned) readbuf;
379
380 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
381
382 if (res < 0) {
383 ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
384 break;
385 }
386
387 res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
388 if (res == 0) {
389 ALOGE("binder_loop: unexpected reply?!\n");
390 break;
391 }
392 if (res < 0) {
393 ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
394 break;
395 }
396 }
397}
398
Serban Constantinescubcf38882014-01-10 13:56:27 +0000399void bio_init_from_txn(struct binder_io *bio, struct binder_transaction_data *txn)
Mike Lockwood94afecf2012-10-24 10:45:23 -0700400{
Serban Constantinescubcf38882014-01-10 13:56:27 +0000401 bio->data = bio->data0 = txn->data.ptr.buffer;
402 bio->offs = bio->offs0 = txn->data.ptr.offsets;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700403 bio->data_avail = txn->data_size;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000404 bio->offs_avail = txn->offsets_size / 4;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700405 bio->flags = BIO_F_SHARED;
406}
407
408void bio_init(struct binder_io *bio, void *data,
409 uint32_t maxdata, uint32_t maxoffs)
410{
411 uint32_t n = maxoffs * sizeof(uint32_t);
412
413 if (n > maxdata) {
414 bio->flags = BIO_F_OVERFLOW;
415 bio->data_avail = 0;
416 bio->offs_avail = 0;
417 return;
418 }
419
420 bio->data = bio->data0 = (char *) data + n;
421 bio->offs = bio->offs0 = data;
422 bio->data_avail = maxdata - n;
423 bio->offs_avail = maxoffs;
424 bio->flags = 0;
425}
426
427static void *bio_alloc(struct binder_io *bio, uint32_t size)
428{
429 size = (size + 3) & (~3);
430 if (size > bio->data_avail) {
431 bio->flags |= BIO_F_OVERFLOW;
432 return 0;
433 } else {
434 void *ptr = bio->data;
435 bio->data += size;
436 bio->data_avail -= size;
437 return ptr;
438 }
439}
440
441void binder_done(struct binder_state *bs,
442 struct binder_io *msg,
443 struct binder_io *reply)
444{
445 if (reply->flags & BIO_F_SHARED) {
446 uint32_t cmd[2];
447 cmd[0] = BC_FREE_BUFFER;
448 cmd[1] = (uint32_t) reply->data0;
449 binder_write(bs, cmd, sizeof(cmd));
450 reply->flags = 0;
451 }
452}
453
Serban Constantinescubcf38882014-01-10 13:56:27 +0000454static struct flat_binder_object *bio_alloc_obj(struct binder_io *bio)
Mike Lockwood94afecf2012-10-24 10:45:23 -0700455{
Serban Constantinescubcf38882014-01-10 13:56:27 +0000456 struct flat_binder_object *obj;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700457
458 obj = bio_alloc(bio, sizeof(*obj));
459
460 if (obj && bio->offs_avail) {
461 bio->offs_avail--;
462 *bio->offs++ = ((char*) obj) - ((char*) bio->data0);
463 return obj;
464 }
465
466 bio->flags |= BIO_F_OVERFLOW;
467 return 0;
468}
469
470void bio_put_uint32(struct binder_io *bio, uint32_t n)
471{
472 uint32_t *ptr = bio_alloc(bio, sizeof(n));
473 if (ptr)
474 *ptr = n;
475}
476
477void bio_put_obj(struct binder_io *bio, void *ptr)
478{
Serban Constantinescubcf38882014-01-10 13:56:27 +0000479 struct flat_binder_object *obj;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700480
481 obj = bio_alloc_obj(bio);
482 if (!obj)
483 return;
484
485 obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
486 obj->type = BINDER_TYPE_BINDER;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000487 obj->binder = ptr;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700488 obj->cookie = 0;
489}
490
491void bio_put_ref(struct binder_io *bio, void *ptr)
492{
Serban Constantinescubcf38882014-01-10 13:56:27 +0000493 struct flat_binder_object *obj;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700494
495 if (ptr)
496 obj = bio_alloc_obj(bio);
497 else
498 obj = bio_alloc(bio, sizeof(*obj));
499
500 if (!obj)
501 return;
502
503 obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
504 obj->type = BINDER_TYPE_HANDLE;
Serban Constantinescubcf38882014-01-10 13:56:27 +0000505 obj->handle = ptr;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700506 obj->cookie = 0;
507}
508
509void bio_put_string16(struct binder_io *bio, const uint16_t *str)
510{
511 uint32_t len;
512 uint16_t *ptr;
513
514 if (!str) {
515 bio_put_uint32(bio, 0xffffffff);
516 return;
517 }
518
519 len = 0;
520 while (str[len]) len++;
521
522 if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
523 bio_put_uint32(bio, 0xffffffff);
524 return;
525 }
526
527 bio_put_uint32(bio, len);
528 len = (len + 1) * sizeof(uint16_t);
529 ptr = bio_alloc(bio, len);
530 if (ptr)
531 memcpy(ptr, str, len);
532}
533
534void bio_put_string16_x(struct binder_io *bio, const char *_str)
535{
536 unsigned char *str = (unsigned char*) _str;
537 uint32_t len;
538 uint16_t *ptr;
539
540 if (!str) {
541 bio_put_uint32(bio, 0xffffffff);
542 return;
543 }
544
545 len = strlen(_str);
546
547 if (len >= (MAX_BIO_SIZE / sizeof(uint16_t))) {
548 bio_put_uint32(bio, 0xffffffff);
549 return;
550 }
551
552 bio_put_uint32(bio, len);
553 ptr = bio_alloc(bio, (len + 1) * sizeof(uint16_t));
554 if (!ptr)
555 return;
556
557 while (*str)
558 *ptr++ = *str++;
559 *ptr++ = 0;
560}
561
562static void *bio_get(struct binder_io *bio, uint32_t size)
563{
564 size = (size + 3) & (~3);
565
566 if (bio->data_avail < size){
567 bio->data_avail = 0;
568 bio->flags |= BIO_F_OVERFLOW;
569 return 0;
570 } else {
571 void *ptr = bio->data;
572 bio->data += size;
573 bio->data_avail -= size;
574 return ptr;
575 }
576}
577
578uint32_t bio_get_uint32(struct binder_io *bio)
579{
580 uint32_t *ptr = bio_get(bio, sizeof(*ptr));
581 return ptr ? *ptr : 0;
582}
583
584uint16_t *bio_get_string16(struct binder_io *bio, unsigned *sz)
585{
586 unsigned len;
587 len = bio_get_uint32(bio);
588 if (sz)
589 *sz = len;
590 return bio_get(bio, (len + 1) * sizeof(uint16_t));
591}
592
Serban Constantinescubcf38882014-01-10 13:56:27 +0000593static struct flat_binder_object *_bio_get_obj(struct binder_io *bio)
Mike Lockwood94afecf2012-10-24 10:45:23 -0700594{
595 unsigned n;
596 unsigned off = bio->data - bio->data0;
597
598 /* TODO: be smarter about this? */
599 for (n = 0; n < bio->offs_avail; n++) {
600 if (bio->offs[n] == off)
Serban Constantinescubcf38882014-01-10 13:56:27 +0000601 return bio_get(bio, sizeof(struct flat_binder_object));
Mike Lockwood94afecf2012-10-24 10:45:23 -0700602 }
603
604 bio->data_avail = 0;
605 bio->flags |= BIO_F_OVERFLOW;
606 return 0;
607}
608
609void *bio_get_ref(struct binder_io *bio)
610{
Serban Constantinescubcf38882014-01-10 13:56:27 +0000611 struct flat_binder_object *obj;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700612
613 obj = _bio_get_obj(bio);
614 if (!obj)
615 return 0;
616
617 if (obj->type == BINDER_TYPE_HANDLE)
Serban Constantinescubcf38882014-01-10 13:56:27 +0000618 return obj->handle;
Mike Lockwood94afecf2012-10-24 10:45:23 -0700619
620 return 0;
621}