• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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