1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "serializer.h"
17 #include "ipc_log.h"
18 #include "securec.h"
19 #include <stdlib.h>
20 #include <string.h>
21 #include "liteipc.h"
22 #ifdef LITE_LINUX_BINDER_IPC
23 #include <pthread.h>
24 #include "sys_binder.h"
25 #endif
26
27 #define MAX_IO_SIZE 8192UL
28 #define MAX_OBJ_NUM 32UL
29 #define MAX_DATA_BUFF_SIZE 65536UL
30
31 #define IPC_IO_INITIALIZED 0x01 /* ipc flag indicates whether io is initialized */
32 #define IPC_IO_OVERFLOW 0x02 /* ipc flag indicates whether io is running out of space */
33
34 #define ALIGN_SZ 4
35 #define IPC_IO_ALIGN(sz) (((sz) + ALIGN_SZ - 1) & (~(ALIGN_SZ - 1)))
36
37 #define IPC_IO_RETURN_IF_FAIL(value) \
38 do { \
39 if (!(value)) { \
40 IPC_LOG_ERROR("IPC_ASSERT failed: %s:%d\n", __FUNCTION__, __LINE__); \
41 if (io != NULL) { \
42 io->flag |= IPC_IO_OVERFLOW; \
43 } \
44 return NULL; \
45 } \
46 } while (0)
47
48 static void* IoPop(IpcIo* io, size_t size);
49
50 typedef struct {
51 #ifndef LITE_LINUX_BINDER_IPC
52 NDK_DL_LIST list;
53 #endif
54 BuffPtr ptr;
55 IpcIoPtrFree ptrFree;
56 } IpcPtrNode;
57
58 extern __thread IpcContext *g_tlsContext;
59
IpcIoInit(IpcIo * io,void * buffer,size_t bufferSize,size_t maxobjects)60 void IpcIoInit(IpcIo* io, void* buffer, size_t bufferSize, size_t maxobjects)
61 {
62 if ((io == NULL) || (buffer == NULL) || (bufferSize == 0) || (bufferSize > MAX_IO_SIZE) || (maxobjects > MAX_OBJ_NUM)) {
63 return;
64 }
65 #ifdef LITE_LINUX_BINDER_IPC
66 maxobjects++;
67 #endif
68 size_t objectsSize = maxobjects * sizeof(size_t);
69
70 if (objectsSize > bufferSize) {
71 io->flag = IPC_IO_OVERFLOW;
72 io->bufferLeft = 0;
73 io->offsetsLeft = 0;
74 return;
75 }
76
77 io->bufferCur = io->bufferBase = (char*)buffer + objectsSize;
78 io->offsetsCur = io->offsetsBase = (size_t*)buffer;
79 io->bufferLeft = bufferSize - objectsSize;
80 io->offsetsLeft = maxobjects;
81 NDK_ListInit(&io->ptrFreeList);
82 io->flag = IPC_IO_INITIALIZED;
83 #ifdef LITE_LINUX_BINDER_IPC
84 SvcIdentity svc = {
85 .handle = 0,
86 .token = pthread_self()
87 };
88 uint32_t token = 0;
89 IpcIoPushUint32(io, token);
90 IpcIoPushSvc(io, &svc);
91 #endif
92 }
93
IpcIoInitFromMsg(IpcIo * io,const void * msg)94 void IpcIoInitFromMsg(IpcIo* io, const void* msg)
95 {
96 if ((io == NULL) || (msg == NULL)) {
97 return;
98 }
99 IpcMsg* local = (IpcMsg*)msg;
100 io->bufferCur = io->bufferBase = (char*)(intptr_t)local->data;
101 io->offsetsCur = io->offsetsBase = (size_t*)(intptr_t)(local->offsets);
102 io->bufferLeft = local->dataSz;
103 io->offsetsLeft = local->spObjNum;
104 NDK_ListInit(&io->ptrFreeList);
105 io->flag = IPC_IO_INITIALIZED;
106 }
107
IpcIoAvailable(IpcIo * io)108 bool IpcIoAvailable(IpcIo* io)
109 {
110 bool ret = false;
111 if (io != NULL) {
112 ret = (io->flag & IPC_IO_INITIALIZED) && !(io->flag & IPC_IO_OVERFLOW);
113 }
114 return ret;
115 }
116
IoPush(IpcIo * io,size_t size)117 static void* IoPush(IpcIo* io, size_t size)
118 {
119 IPC_IO_RETURN_IF_FAIL(io != NULL);
120 IPC_IO_RETURN_IF_FAIL(IpcIoAvailable(io));
121 size = IPC_IO_ALIGN(size);
122 if (size > io->bufferLeft) {
123 io->flag |= IPC_IO_OVERFLOW;
124 return NULL;
125 } else {
126 void* ptr = io->bufferCur;
127 io->bufferCur += size;
128 io->bufferLeft -= size;
129 return ptr;
130 }
131 }
132
IoPushUnaligned(IpcIo * io,size_t size)133 static void* IoPushUnaligned(IpcIo* io, size_t size)
134 {
135 IPC_IO_RETURN_IF_FAIL(io != NULL);
136 IPC_IO_RETURN_IF_FAIL(IpcIoAvailable(io));
137 if (size > io->bufferLeft) {
138 io->flag |= IPC_IO_OVERFLOW;
139 return NULL;
140 } else {
141 void* ptr = io->bufferCur;
142 io->bufferCur += size;
143 io->bufferLeft -= size;
144 return ptr;
145 }
146 }
147
IpcIoPushInt32(IpcIo * io,int32_t n)148 void IpcIoPushInt32(IpcIo* io, int32_t n)
149 {
150 int32_t* ptr = (int32_t*)IoPush(io, sizeof(n));
151 if (ptr != NULL) {
152 *ptr = n;
153 }
154 }
155
IpcIoPushUint32(IpcIo * io,uint32_t n)156 void IpcIoPushUint32(IpcIo* io, uint32_t n)
157 {
158 uint32_t* ptr = (uint32_t*)IoPush(io, sizeof(n));
159 if (ptr != NULL) {
160 *ptr = n;
161 }
162 }
163
IpcIoPushChar(IpcIo * io,char c)164 void IpcIoPushChar(IpcIo* io, char c)
165 {
166 IpcIoPushInt32(io, (int32_t)c);
167 }
168
IpcIoPushCharUnaligned(IpcIo * io,char c)169 void IpcIoPushCharUnaligned(IpcIo* io, char c)
170 {
171 char* ptr = (char*)IoPushUnaligned(io, sizeof(c));
172 if (ptr != NULL) {
173 *ptr = c;
174 }
175 }
176
IpcIoPushBool(IpcIo * io,bool b)177 void IpcIoPushBool(IpcIo* io, bool b)
178 {
179 IpcIoPushInt32(io, (int32_t)b);
180 }
181
IpcIoPushBoolUnaligned(IpcIo * io,bool b)182 void IpcIoPushBoolUnaligned(IpcIo* io, bool b)
183 {
184 bool* ptr = (bool*)IoPushUnaligned(io, sizeof(b));
185 if (ptr != NULL) {
186 *ptr = b;
187 }
188 }
189
IpcIoPushIntptr(IpcIo * io,intptr_t intptr)190 void IpcIoPushIntptr(IpcIo* io, intptr_t intptr)
191 {
192 intptr_t* ptr = (intptr_t*)IoPush(io, sizeof(intptr));
193 if (ptr != NULL) {
194 *ptr = intptr;
195 }
196 }
197
IpcIoPushUintptr(IpcIo * io,uintptr_t uintptr)198 void IpcIoPushUintptr(IpcIo* io, uintptr_t uintptr)
199 {
200 uintptr_t* ptr = (uintptr_t*)IoPush(io, sizeof(uintptr));
201 if (ptr != NULL) {
202 *ptr = uintptr;
203 }
204 }
205
IpcIoPushInt8(IpcIo * io,int8_t n)206 void IpcIoPushInt8(IpcIo* io, int8_t n)
207 {
208 IpcIoPushInt32(io, (int32_t)n);
209 }
210
IpcIoPushInt8Unaligned(IpcIo * io,int8_t n)211 void IpcIoPushInt8Unaligned(IpcIo* io, int8_t n)
212 {
213 int8_t* ptr = (int8_t*)IoPushUnaligned(io, sizeof(n));
214 if (ptr != NULL) {
215 *ptr = n;
216 }
217 }
218
IpcIoPushUint8(IpcIo * io,uint8_t n)219 void IpcIoPushUint8(IpcIo* io, uint8_t n)
220 {
221 IpcIoPushUint32(io, (uint32_t)n);
222 }
223
IpcIoPushUint8Unaligned(IpcIo * io,uint8_t n)224 void IpcIoPushUint8Unaligned(IpcIo* io, uint8_t n)
225 {
226 uint8_t* ptr = (uint8_t*)IoPushUnaligned(io, sizeof(n));
227 if (ptr != NULL) {
228 *ptr = n;
229 }
230 }
231
IpcIoPushInt16(IpcIo * io,int16_t n)232 void IpcIoPushInt16(IpcIo* io, int16_t n)
233 {
234 IpcIoPushInt32(io, (int32_t)n);
235 }
236
IpcIoPushInt16Unaligned(IpcIo * io,int16_t n)237 void IpcIoPushInt16Unaligned(IpcIo* io, int16_t n)
238 {
239 int16_t* ptr = (int16_t*)IoPushUnaligned(io, sizeof(n));
240 if (ptr != NULL) {
241 *ptr = n;
242 }
243 }
244
IpcIoPushUint16(IpcIo * io,uint16_t n)245 void IpcIoPushUint16(IpcIo* io, uint16_t n)
246 {
247 IpcIoPushUint32(io, (uint32_t)n);
248 }
249
IpcIoPushUint16Unaligned(IpcIo * io,uint16_t n)250 void IpcIoPushUint16Unaligned(IpcIo* io, uint16_t n)
251 {
252 uint16_t* ptr = (uint16_t*)IoPushUnaligned(io, sizeof(n));
253 if (ptr != NULL) {
254 *ptr = n;
255 }
256 }
257
IpcIoPushInt64(IpcIo * io,int64_t n)258 void IpcIoPushInt64(IpcIo* io, int64_t n)
259 {
260 int64_t* ptr = (int64_t*)IoPush(io, sizeof(n));
261 if (ptr != NULL) {
262 *ptr = n;
263 }
264 }
265
IpcIoPushUint64(IpcIo * io,uint64_t n)266 void IpcIoPushUint64(IpcIo* io, uint64_t n)
267 {
268 uint64_t* ptr = (uint64_t*)IoPush(io, sizeof(n));
269 if (ptr != NULL) {
270 *ptr = n;
271 }
272 }
273
IpcIoPushFloat(IpcIo * io,float n)274 void IpcIoPushFloat(IpcIo* io, float n)
275 {
276 float* ptr = (float*)IoPush(io, sizeof(n));
277 if (ptr != NULL) {
278 *ptr = n;
279 }
280 }
281
IpcIoPushDouble(IpcIo * io,double n)282 void IpcIoPushDouble(IpcIo* io, double n)
283 {
284 double* ptr = (double*)IoPush(io, sizeof(n));
285 if (ptr != NULL) {
286 *ptr = n;
287 }
288 }
289
IpcIoPushString(IpcIo * io,const char * cstr)290 void IpcIoPushString(IpcIo* io, const char* cstr)
291 {
292 unsigned char* str = (unsigned char*)cstr;
293 size_t len;
294 uint8_t* ptr = NULL;
295
296 if (io == NULL) {
297 return;
298 }
299 if (str == NULL) {
300 io->flag |= IPC_IO_OVERFLOW;
301 return;
302 }
303
304 #ifdef LITE_LINUX_BINDER_IPC
305 len = strlen(cstr);
306 #else
307 len = strnlen(cstr, MAX_IO_SIZE);
308 #endif
309 if (len == MAX_IO_SIZE) {
310 io->flag |= IPC_IO_OVERFLOW;
311 return;
312 }
313
314 /* Note: The payload will carry 32bit size instead of size_t */
315 IpcIoPushUint32(io, (uint32_t)len);
316 ptr = (uint8_t*)IoPush(io, len + 1);
317 if (ptr != NULL) {
318 if (memset_s(ptr, IPC_IO_ALIGN(len + 1), 0, IPC_IO_ALIGN(len + 1)) != EOK) {
319 io->flag |= IPC_IO_OVERFLOW;
320 return;
321 }
322 if (memcpy_s(ptr, IPC_IO_ALIGN(len + 1), str, len + 1) != EOK) {
323 io->flag |= IPC_IO_OVERFLOW;
324 }
325 }
326 }
327
IpcIoPushFlatObj(IpcIo * io,const void * obj,uint32_t size)328 void IpcIoPushFlatObj(IpcIo* io, const void* obj, uint32_t size)
329 {
330 if (io == NULL) {
331 return;
332 }
333 if ((obj == NULL) || (size == 0) || (size > MAX_IO_SIZE)) {
334 io->flag |= IPC_IO_OVERFLOW;
335 return;
336 }
337 IpcIoPushUint32(io, size);
338 int32_t* ptr = (int32_t*)IoPush(io, size);
339 if (ptr != NULL) {
340 if (memcpy_s(ptr, size, obj, size) != EOK) {
341 io->flag |= IPC_IO_OVERFLOW;
342 }
343 }
344 }
345
346
347
348 #ifdef LITE_LINUX_BINDER_IPC
IoPushBinderObj(IpcIo * io)349 static struct flat_binder_object* IoPushBinderObj(IpcIo* io)
350 {
351 IPC_IO_RETURN_IF_FAIL(io != NULL);
352 IPC_IO_RETURN_IF_FAIL(io->offsetsCur != NULL);
353 struct flat_binder_object* ptr = NULL;
354 ptr = IoPush(io, sizeof(struct flat_binder_object));
355 if ((ptr != NULL) && io->offsetsLeft) {
356 io->offsetsLeft--;
357 *(io->offsetsCur) = (char*)ptr - (char*)io->bufferBase;
358 io->offsetsCur++;
359 return ptr;
360 } else {
361 io->flag |= IPC_IO_OVERFLOW;
362 return NULL;
363 }
364 }
365
IpcIoPushFd(IpcIo * io,uint32_t fd)366 void IpcIoPushFd(IpcIo* io, uint32_t fd)
367 {
368 if (io == NULL) {
369 return;
370 }
371 struct flat_binder_object* ptr = IoPushBinderObj(io);
372 if (ptr == NULL) {
373 printf("[%s:%s:%d]IpcIoPushFd failed.\n", __FILE__, __FUNCTION__, __LINE__);
374 return;
375 }
376 ptr->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
377 ptr->type = BINDER_TYPE_FD;
378 ptr->binder = 0;
379 ptr->cookie = 1;
380 ptr->handle = fd;
381 }
IpcIoPushObject(IpcIo * io,uint32_t token,uint32_t cookie)382 void IpcIoPushObject(IpcIo* io, uint32_t token, uint32_t cookie)
383 {
384 if (io == NULL) {
385 return;
386 }
387 struct flat_binder_object* ptr = IoPushBinderObj(io);
388 if (ptr == NULL) {
389 return;
390 }
391 ptr->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
392 ptr->type = BINDER_TYPE_BINDER;
393 ptr->binder = (uintptr_t)token;
394 ptr->cookie = ptr->binder;
395 }
396
IpcIoPushRef(IpcIo * io,uint32_t handle,uint32_t cookie)397 void IpcIoPushRef(IpcIo* io, uint32_t handle, uint32_t cookie)
398 {
399 if (io == NULL) {
400 return;
401 }
402 struct flat_binder_object* ptr = IoPushBinderObj(io);
403 if (ptr == NULL) {
404 return;
405 }
406 ptr->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
407 ptr->type = BINDER_TYPE_HANDLE;
408 ptr->handle = handle;
409 ptr->cookie = cookie;
410 }
411
IpcIoPopRef(IpcIo * io)412 struct flat_binder_object* IpcIoPopRef(IpcIo *io)
413 {
414 IPC_IO_RETURN_IF_FAIL(io != NULL);
415 IPC_IO_RETURN_IF_FAIL(io->offsetsCur != NULL);
416 if (io->offsetsLeft == 0) {
417 io->flag |= IPC_IO_OVERFLOW;
418 return NULL;
419 }
420 struct flat_binder_object* obj = (struct flat_binder_object*)IoPop(io, sizeof(struct flat_binder_object));
421 if (obj != NULL) {
422 io->offsetsCur++;
423 io->offsetsLeft--;
424 return obj;
425 }
426 return NULL;
427 }
IpcIoPushSvc(IpcIo * io,const SvcIdentity * svc)428 void IpcIoPushSvc(IpcIo* io, const SvcIdentity* svc)
429 {
430 if (io == NULL) {
431 return;
432 }
433 if ((svc->handle == 0) || (svc->handle == MIN_BINDER_HANDLE)) {
434 IpcIoPushObject(io, svc->token, svc->cookie);
435 } else {
436 IpcIoPushRef(io, svc->handle, svc->cookie);
437 }
438 IpcIoPushUint32(io, svc->token);
439 }
440
IpcIoPopSvc(IpcIo * io)441 SvcIdentity* IpcIoPopSvc(IpcIo* io)
442 {
443 if (io == NULL) {
444 return NULL;
445 }
446 SvcIdentity* svc = calloc(1, sizeof(SvcIdentity));
447 if (svc == NULL) {
448 return NULL;
449 }
450 struct flat_binder_object* obj = IpcIoPopRef(io);
451 if (obj == NULL) {
452 IPC_LOG_ERROR("IpcIoPopSvc failed: obj is null");
453 return NULL;
454 }
455 svc->token = IpcIoPopUint32(io);
456 if (obj->type == BINDER_TYPE_BINDER) {
457 svc->token = obj->binder;
458 svc->handle = MIN_BINDER_HANDLE;
459 svc->cookie = obj->cookie;
460 } else {
461 svc->handle = obj->handle;
462 svc->cookie = obj->cookie;
463 }
464 svc->ipcContext = g_tlsContext;
465 return svc;
466 }
467 #else
IoPopSpecObj(IpcIo * io)468 static SpecialObj* IoPopSpecObj(IpcIo* io)
469 {
470 IPC_IO_RETURN_IF_FAIL(io != NULL);
471 IPC_IO_RETURN_IF_FAIL(io->offsetsCur != NULL);
472 if ((io->offsetsLeft == 0) || (*(io->offsetsCur) != io->bufferCur - io->bufferBase)) {
473 goto ERROR;
474 }
475
476 SpecialObj* obj = IoPop(io, sizeof(SpecialObj));
477 if (obj != NULL) {
478 io->offsetsCur++;
479 io->offsetsLeft--;
480 return obj;
481 }
482
483 ERROR:
484 io->flag |= IPC_IO_OVERFLOW;
485 return NULL;
486 }
487
IoPushSpecObj(IpcIo * io)488 static SpecialObj* IoPushSpecObj(IpcIo* io)
489 {
490 IPC_IO_RETURN_IF_FAIL(io != NULL);
491 IPC_IO_RETURN_IF_FAIL(io->offsetsCur != NULL);
492 SpecialObj* ptr = NULL;
493 ptr = IoPush(io, sizeof(SpecialObj));
494 if ((ptr != NULL) && io->offsetsLeft) {
495 io->offsetsLeft--;
496 *(io->offsetsCur) = (char*)ptr - io->bufferBase;
497 io->offsetsCur++;
498 return ptr;
499 } else {
500 io->flag |= IPC_IO_OVERFLOW;
501 return NULL;
502 }
503 }
504
IpcIoPushFd(IpcIo * io,uint32_t fd)505 void IpcIoPushFd(IpcIo* io, uint32_t fd)
506 {
507 SpecialObj* ptr = IoPushSpecObj(io);
508
509 if (ptr != NULL) {
510 ptr->type = OBJ_FD;
511 ptr->content.fd = fd;
512 }
513 }
514
IpcIoPushSvc(IpcIo * io,const SvcIdentity * svc)515 void IpcIoPushSvc(IpcIo* io, const SvcIdentity* svc)
516 {
517 if (io == NULL) {
518 return;
519 }
520 if (svc == NULL) {
521 io->flag |= IPC_IO_OVERFLOW;
522 return;
523 }
524 SpecialObj* ptr = IoPushSpecObj(io);
525
526 if (ptr != NULL) {
527 ptr->type = OBJ_SVC;
528 ptr->content.svc.handle = svc->handle;
529 ptr->content.svc.token = svc->token;
530 }
531 }
532
IpcIoPopSvc(IpcIo * io)533 SvcIdentity* IpcIoPopSvc(IpcIo* io)
534 {
535 SpecialObj* ptr = IoPopSpecObj(io);
536 if (ptr == NULL || ptr->type != OBJ_SVC) {
537 return NULL;
538 } else {
539 return &(ptr->content.svc);
540 }
541 }
542 #endif
543
544 #ifndef LITE_LINUX_BINDER_IPC
IpcIoPushDataBuff(IpcIo * io,const BuffPtr * dataBuff)545 void IpcIoPushDataBuff(IpcIo* io, const BuffPtr* dataBuff)
546 {
547 if (io == NULL) {
548 return;
549 }
550 if ((dataBuff == NULL) || (dataBuff->buff == NULL) ||
551 (dataBuff->buffSz == 0) || (dataBuff->buffSz > MAX_DATA_BUFF_SIZE)) {
552 io->flag |= IPC_IO_OVERFLOW;
553 return;
554 }
555 SpecialObj* ptr = IoPushSpecObj(io);
556 if (ptr != NULL) {
557 ptr->type = OBJ_PTR;
558 ptr->content.ptr.buff = dataBuff->buff;
559 ptr->content.ptr.buffSz = dataBuff->buffSz;
560 }
561 }
562
IpcIoPushDataBuffWithFree(IpcIo * io,const BuffPtr * dataBuff,IpcIoPtrFree ipcIoFree)563 void IpcIoPushDataBuffWithFree(IpcIo* io, const BuffPtr* dataBuff, IpcIoPtrFree ipcIoFree)
564 {
565 IpcIoPushDataBuff(io, dataBuff);
566 if ((ipcIoFree != NULL) && IpcIoAvailable(io)) {
567 IpcPtrNode* node = malloc(sizeof(IpcPtrNode));
568 if (node == NULL) {
569 io->flag |= IPC_IO_OVERFLOW;
570 return;
571 }
572 node->ptr = *dataBuff;
573 node->ptrFree = ipcIoFree;
574 NDK_ListAdd(&io->ptrFreeList, &node->list);
575 }
576 }
577
IpcIoFreeDataBuff(IpcIo * io)578 void IpcIoFreeDataBuff(IpcIo* io)
579 {
580 IpcPtrNode* node = NULL;
581 if ((io == NULL) || (io->ptrFreeList.pstNext == NULL) || (io->ptrFreeList.pstPrev == NULL)) {
582 return;
583 }
584 while (!NDK_ListEmpty(&io->ptrFreeList)) {
585 node = NDK_DL_LIST_ENTRY(io->ptrFreeList.pstNext, IpcPtrNode, list);
586 if (node->ptrFree != NULL && node->ptr.buff != NULL) {
587 node->ptrFree(node->ptr.buff);
588 }
589 NDK_ListDelete(&node->list);
590 free(node);
591 }
592 }
593 #else
IpcIoPushDataBuff(IpcIo * io,const BuffPtr * dataBuff)594 void IpcIoPushDataBuff(IpcIo* io, const BuffPtr* dataBuff)
595 {
596 }
597
IpcIoPushDataBuffWithFree(IpcIo * io,const BuffPtr * dataBuff,IpcIoPtrFree ipcIoFree)598 void IpcIoPushDataBuffWithFree(IpcIo* io, const BuffPtr* dataBuff, IpcIoPtrFree ipcIoFree)
599 {
600 }
601
IpcIoFreeDataBuff(IpcIo * io)602 void IpcIoFreeDataBuff(IpcIo* io)
603 {
604 }
605 #endif
606
IoPop(IpcIo * io,size_t size)607 static void* IoPop(IpcIo* io, size_t size)
608 {
609 IPC_IO_RETURN_IF_FAIL(io != NULL);
610 IPC_IO_RETURN_IF_FAIL(IpcIoAvailable(io));
611 size = IPC_IO_ALIGN(size);
612
613 if (io->bufferLeft < size) {
614 io->bufferLeft = 0;
615 io->flag |= IPC_IO_OVERFLOW;
616 return NULL;
617 } else {
618 void* ptr = io->bufferCur;
619 io->bufferCur += size;
620 io->bufferLeft -= size;
621 return ptr;
622 }
623 }
624
IoPopUnaligned(IpcIo * io,size_t size)625 static void* IoPopUnaligned(IpcIo* io, size_t size)
626 {
627 IPC_IO_RETURN_IF_FAIL(io != NULL);
628 IPC_IO_RETURN_IF_FAIL(IpcIoAvailable(io));
629
630 if (io->bufferLeft < size) {
631 io->bufferLeft = 0;
632 io->flag |= IPC_IO_OVERFLOW;
633 return NULL;
634 } else {
635 void* ptr = io->bufferCur;
636 io->bufferCur += size;
637 io->bufferLeft -= size;
638 return ptr;
639 }
640 }
641
IpcIoPopChar(IpcIo * io)642 char IpcIoPopChar(IpcIo* io)
643 {
644 char* ptr = (char*)IoPop(io, sizeof(*ptr));
645 return ptr ? *ptr : 0;
646 }
647
IpcIoPopCharUnaligned(IpcIo * io)648 char IpcIoPopCharUnaligned(IpcIo* io)
649 {
650 char* ptr = (char*)IoPopUnaligned(io, sizeof(*ptr));
651 return ptr ? *ptr : 0;
652 }
653
IpcIoPopBool(IpcIo * io)654 bool IpcIoPopBool(IpcIo* io)
655 {
656 bool* ptr = (bool*)IoPop(io, sizeof(*ptr));
657 return ptr ? *ptr : 0;
658 }
659
IpcIoPopBoolUnaligned(IpcIo * io)660 bool IpcIoPopBoolUnaligned(IpcIo* io)
661 {
662 bool* ptr = (bool*)IoPopUnaligned(io, sizeof(*ptr));
663 return ptr ? *ptr : 0;
664 }
665
IpcIoPopIntptr(IpcIo * io)666 intptr_t IpcIoPopIntptr(IpcIo* io)
667 {
668 intptr_t* ptr = (intptr_t*)IoPop(io, sizeof(*ptr));
669 return ptr ? *ptr : 0;
670 }
671
IpcIoPopUintptr(IpcIo * io)672 uintptr_t IpcIoPopUintptr(IpcIo* io)
673 {
674 uintptr_t* ptr = (uintptr_t*)IoPop(io, sizeof(*ptr));
675 return ptr ? *ptr : 0;
676 }
677
IpcIoPopInt8(IpcIo * io)678 int8_t IpcIoPopInt8(IpcIo* io)
679 {
680 int8_t* ptr = (int8_t*)IoPop(io, sizeof(*ptr));
681 return ptr ? *ptr : 0;
682 }
683
IpcIoPopInt8Unaligned(IpcIo * io)684 int8_t IpcIoPopInt8Unaligned(IpcIo* io)
685 {
686 int8_t* ptr = (int8_t*)IoPopUnaligned(io, sizeof(*ptr));
687 return ptr ? *ptr : 0;
688 }
689
IpcIoPopUint8(IpcIo * io)690 uint8_t IpcIoPopUint8(IpcIo* io)
691 {
692 uint8_t* ptr = (uint8_t*)IoPop(io, sizeof(*ptr));
693 return ptr ? *ptr : 0;
694 }
695
IpcIoPopUint8Unaligned(IpcIo * io)696 uint8_t IpcIoPopUint8Unaligned(IpcIo* io)
697 {
698 uint8_t* ptr = (uint8_t*)IoPopUnaligned(io, sizeof(*ptr));
699 return ptr ? *ptr : 0;
700 }
701
IpcIoPopInt16(IpcIo * io)702 int16_t IpcIoPopInt16(IpcIo* io)
703 {
704 int16_t* ptr = (int16_t*)IoPop(io, sizeof(*ptr));
705 return ptr ? *ptr : 0;
706 }
707
IpcIoPopInt16Unaligned(IpcIo * io)708 int16_t IpcIoPopInt16Unaligned(IpcIo* io)
709 {
710 int16_t* ptr = (int16_t*)IoPopUnaligned(io, sizeof(*ptr));
711 return ptr ? *ptr : 0;
712 }
713
IpcIoPopUint16(IpcIo * io)714 uint16_t IpcIoPopUint16(IpcIo* io)
715 {
716 uint16_t* ptr = (uint16_t*)IoPop(io, sizeof(*ptr));
717 return ptr ? *ptr : 0;
718 }
719
IpcIoPopUint16Unaligned(IpcIo * io)720 uint16_t IpcIoPopUint16Unaligned(IpcIo* io)
721 {
722 uint16_t* ptr = (uint16_t*)IoPopUnaligned(io, sizeof(*ptr));
723 return ptr ? *ptr : 0;
724 }
725
IpcIoPopInt32(IpcIo * io)726 int32_t IpcIoPopInt32(IpcIo* io)
727 {
728 int32_t* ptr = (int32_t*)IoPop(io, sizeof(*ptr));
729 return ptr ? *ptr : 0;
730 }
731
IpcIoPopUint32(IpcIo * io)732 uint32_t IpcIoPopUint32(IpcIo* io)
733 {
734 uint32_t* ptr = (uint32_t*)IoPop(io, sizeof(*ptr));
735 return ptr ? *ptr : 0;
736 }
737
IpcIoPopInt64(IpcIo * io)738 int64_t IpcIoPopInt64(IpcIo* io)
739 {
740 int64_t* ptr = (int64_t*)IoPop(io, sizeof(*ptr));
741 return ptr ? *ptr : 0;
742 }
743
IpcIoPopUint64(IpcIo * io)744 uint64_t IpcIoPopUint64(IpcIo* io)
745 {
746 uint64_t* ptr = (uint64_t*)IoPop(io, sizeof(*ptr));
747 return ptr ? *ptr : 0;
748 }
749
IpcIoPopFloat(IpcIo * io)750 float IpcIoPopFloat(IpcIo* io)
751 {
752 float* ptr = (float*)IoPop(io, sizeof(*ptr));
753 return ptr ? *ptr : 0;
754 }
755
IpcIoPopDouble(IpcIo * io)756 double IpcIoPopDouble(IpcIo* io)
757 {
758 double* ptr = (double*)IoPop(io, sizeof(*ptr));
759 return ptr ? *ptr : 0;
760 }
761
IpcIoPopString(IpcIo * io,size_t * sz)762 uint8_t* IpcIoPopString(IpcIo* io, size_t* sz)
763 {
764 size_t len;
765
766 /* Note: The payload will carry 32bit size instead of size_t */
767 len = (size_t)IpcIoPopUint32(io);
768 if (sz != NULL) {
769 *sz = len;
770 }
771 if (len > MAX_IO_SIZE) {
772 return NULL;
773 }
774 return (uint8_t*)IoPop(io, len + 1);
775 }
776
IpcIoPopFlatObj(IpcIo * io,uint32_t * size)777 void* IpcIoPopFlatObj(IpcIo* io, uint32_t* size)
778 {
779 IPC_IO_RETURN_IF_FAIL(size != NULL);
780 *size = (size_t)IpcIoPopUint32(io);
781 if (*size > MAX_IO_SIZE) {
782 return NULL;
783 }
784 return (void*)IoPop(io, *size);
785 }
786
787
788
789 #ifndef LITE_LINUX_BINDER_IPC
IpcIoPopFd(IpcIo * io)790 int32_t IpcIoPopFd(IpcIo* io)
791 {
792 SpecialObj* ptr = IoPopSpecObj(io);
793 if (ptr == NULL || ptr->type != OBJ_FD) {
794 return -1;
795 } else {
796 return ptr->content.fd;
797 }
798 }
799
IpcIoPopDataBuff(IpcIo * io)800 BuffPtr* IpcIoPopDataBuff(IpcIo* io)
801 {
802 SpecialObj* ptr = IoPopSpecObj(io);
803 if (ptr == NULL || ptr->type != OBJ_PTR) {
804 return NULL;
805 } else {
806 return &(ptr->content.ptr);
807 }
808 }
809 #else
IpcIoPopFd(IpcIo * io)810 int32_t IpcIoPopFd(IpcIo* io)
811 {
812 if (io == NULL) {
813 return -1;
814 }
815 struct flat_binder_object* obj = IpcIoPopRef(io);
816 if (obj == NULL) {
817 IPC_LOG_ERROR("IpcIoPopFd failed: obj is null");
818 return -1;
819 }
820 if (obj && obj->type == BINDER_TYPE_FD) {
821 return obj->handle;
822 }
823 IPC_LOG_ERROR("IpcIoPopFd failed: type:%d", obj->type);
824 return -1;
825 }
826
IpcIoPopDataBuff(IpcIo * io)827 BuffPtr* IpcIoPopDataBuff(IpcIo* io)
828 {
829 (void)io;
830 return NULL;
831 }
832 #endif
833