• 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 "liteipc_adapter.h"
17 #include <fcntl.h>
18 #include <pthread.h>
19 #include <sched.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/ioctl.h>
23 #include <sys/mman.h>
24 #include <sys/types.h>
25 #include <signal.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include "liteipc.h"
29 #include "securec.h"
30 #include "sys_binder.h"
31 #include "utils_list.h"
32 
33 #define ALIGN_SZ 4
34 #define IPC_IO_ALIGN(sz) (((sz) + ALIGN_SZ - 1) & (~(ALIGN_SZ - 1)))
35 #define SET_MAX_THREADS 4
36 #define BINDER_DRIVER "/dev/binder"
37 #define IPC_IO_DATA_TEMP 200
38 #define READ_BUFFER_SIZE 32
39 
40 #define NS_PER_MS  1000000ULL
41 #define NS_PER_SEC 1000000000ULL
42 static UTILS_DL_LIST *g_tempHandles = NULL;
43 static UTILS_DL_LIST *g_funcPairs = NULL;
44 static pthread_mutex_t g_funcPairsMutex = PTHREAD_MUTEX_INITIALIZER;
45 static uint32_t g_samgrId = 0;
46 static uint32_t g_handle = 0;
47 static bool g_isStartLoop = false;
48 __thread const IpcContext *g_tlsContext = NULL;
49 __thread IpcIo **g_tlsReply = NULL;
50 __thread uint8_t g_tlsReplyData[IPC_IO_DATA_MAX] = {0};
51 bool g_init = 0;
52 struct TransactData {
53     uint32_t cmd;
54     struct binder_transaction_data btd;
55 }__attribute__((packed));
56 
57 struct FreeData {
58     uint32_t cmd;
59     binder_uintptr_t buffer;
60 }__attribute__((packed));
61 
62 static void RemoveDeathCallback(uint32_t handle);
63 typedef struct {
64     pthread_mutex_t mutex;
65     int32_t handleId;
66     bool threadWorking;
67     UTILS_DL_LIST apis;
68     UTILS_DL_LIST testaments;
69 } IpcCallbackCb;
70 
71 IpcCallbackCb g_ipcCallbackCb = {
72     .mutex = PTHREAD_MUTEX_INITIALIZER,
73     .handleId = -1,
74     .threadWorking = false
75 };
76 
77 typedef struct {
78     bool usedFlag;
79     IpcMsgHandler hdler;
80     void* arg;
81 } IpcMsgHandlerPair;
82 
83 typedef struct {
84     UTILS_DL_LIST list;
85     uint32_t handle;
86     IpcMsgHandlerPair hdlerPairs[MAX_DEATHCB_PER_SVC];
87     size_t size;
88     bool isCallbackRuning;
89 } Testament;
90 
91 typedef struct {
92     UTILS_DL_LIST list;
93     uint32_t token;
94     IpcMsgHandlerPair hdlerPair;
95 } AnonymousApi;
96 
97 typedef struct {
98     uint32_t num;
99     void* msg;
100     IpcIo io;
101     IpcMsgHandlerPair* cbs;
102     const IpcContext* context;
103 } HdlerArg;
104 
105 struct BinderDeath {
106     IpcMsgHandler func;
107     uint32_t token;
108 };
109 
110 struct FuncPair {
111     UTILS_DL_LIST list;
112     pthread_t tid;
113     IpcMsgHandler func;
114     void* argv;
115 };
116 
117 struct BinderThreadDesc {
118     const IpcContext* context;
119     IpcMsgHandler func;
120     void* argv;
121 };
122 
123 #define LOG(level, format, ...)                      \
124     do {                                             \
125         printf("[%s : %d]", __FUNCTION__, __LINE__); \
126         printf(format, ##__VA_ARGS__);               \
127         printf("\n");                                \
128     } while (0)
129 
130 #define RETURN_IF_IPC_IOCTL_FAILED(retVal)              \
131     do {                                                \
132         if (ret < 0) {                                  \
133             LOG(ERROR, "Liteipc driver ioctl failed."); \
134             return (retVal);                            \
135         }                                               \
136     } while (0)
137 
InitCallbackCb()138 static inline void InitCallbackCb()
139 {
140     UtilsListInit(&g_ipcCallbackCb.apis);
141     UtilsListInit(&g_ipcCallbackCb.testaments);
142     g_init = 1;
143 }
144 
145 static int32_t StartCallbackDispatch(const IpcContext *context);
146 
SaveFuncPair(const struct FuncPair * func)147 static void SaveFuncPair(const struct FuncPair* func)
148 {
149     if (g_funcPairs == NULL) {
150         return;
151     }
152     struct FuncPair* node = NULL;
153     struct FuncPair* next = NULL;
154     if (pthread_mutex_lock(&g_funcPairsMutex) != 0) {
155         LOG(ERROR, "Get save fun pair mutex failed.");
156         return;
157     }
158     uint32_t curTid = (uint32_t)pthread_self();
159     UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, g_funcPairs, struct FuncPair, list)
160     {
161         if (node->tid != curTid) {
162             continue;
163         }
164         node->func = func->func;
165         node->argv = func->argv;
166         (void)pthread_mutex_unlock(&g_funcPairsMutex);
167         return;
168     }
169 
170     node = calloc(1, sizeof(struct FuncPair));
171     if (node == NULL) {
172         (void)pthread_mutex_unlock(&g_funcPairsMutex);
173         return;
174     }
175     node->func = func->func;
176     node->argv = func->argv;
177     node->tid = curTid;
178     UtilsListAdd(g_funcPairs, &node->list);
179     (void)pthread_mutex_unlock(&g_funcPairsMutex);
180 }
181 
GetFuncPair(struct FuncPair * func,uint32_t target)182 static bool GetFuncPair(struct FuncPair* func, uint32_t target)
183 {
184     if (g_funcPairs == NULL) {
185         return false;
186     }
187     struct FuncPair* node = NULL;
188     struct FuncPair* next = NULL;
189     if (pthread_mutex_lock(&g_funcPairsMutex) != 0) {
190         LOG(ERROR, "Get callback mutex failed.");
191         return false;
192     }
193     UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, g_funcPairs, struct FuncPair, list)
194     {
195         if (node->tid != target) {
196             continue;
197         }
198         func->func = node->func;
199         func->argv = node->argv;
200         (void)pthread_mutex_unlock(&g_funcPairsMutex);
201         return true;
202     }
203     (void)pthread_mutex_unlock(&g_funcPairsMutex);
204     return false;
205 }
206 
CheckIpcIo(IpcIo * data)207 static int32_t CheckIpcIo(IpcIo* data)
208 {
209     uint32_t totalSize;
210     /* It's OK if data is null */
211     if (data == NULL) {
212         return LITEIPC_OK;
213     }
214     if ((IpcIoAvailable(data) == false) ||
215         (data->bufferCur == NULL) ||
216         (data->bufferBase == NULL) ||
217         (data->offsetsCur == NULL) ||
218         (data->offsetsBase == NULL)) {
219         return LITEIPC_EINVAL;
220     }
221     totalSize = data->bufferCur- data->bufferBase + ((char*)data->offsetsCur - (char*)data->offsetsBase);
222     if (totalSize > IPC_IO_DATA_MAX) {
223         LOG(ERROR, "IpcIo data too big, please use IpcIoPushDataBuff to push big data.");
224         return LITEIPC_EINVAL;
225     }
226     return LITEIPC_OK;
227 }
228 
BinderSetMaxthreads(const IpcContext * context,int threads)229 static int BinderSetMaxthreads(const IpcContext* context, int threads)
230 {
231     if (context == NULL) {
232         return LITEIPC_EINTNL;
233     }
234     int ret = ioctl(context->fd, BINDER_SET_MAX_THREADS, &threads);
235     return ret;
236 }
237 
OpenLiteIpc(size_t mmapSize)238 IpcContext* OpenLiteIpc(size_t mmapSize)
239 {
240     if ((mmapSize == 0) || (mmapSize > MMAP_MAX_SIZE)) {
241         LOG(ERROR, "MmapSize not available");
242         return NULL;
243     }
244     IpcContext* context = (IpcContext *)malloc(sizeof(IpcContext));
245     if (context == NULL) {
246         return NULL;
247     }
248     context->fd = open(BINDER_DRIVER, O_RDONLY);
249     if (context->fd < 0) {
250         LOG(ERROR, "Open liteipc driver failed error %s.", strerror(errno));
251         goto OPEN_ERR;
252     }
253 
254     context->mmapAddr = mmap(NULL, mmapSize, PROT_READ, MAP_PRIVATE, context->fd, 0);
255     if (context->mmapAddr == MAP_FAILED) {
256         LOG(ERROR, "Mmap failed.(size=%zu)", mmapSize);
257         goto MMAP_ERR;
258     }
259 
260     context->mmapSize = mmapSize;
261     InitCallbackCb();
262     if (BinderSetMaxthreads(context, SET_MAX_THREADS) != LITEIPC_OK) {
263         LOG(ERROR, "set max threads failed");
264         goto MALLOC_ERR;
265     }
266     return context;
267 
268 MALLOC_ERR:
269     munmap(context->mmapAddr, mmapSize);
270 MMAP_ERR:
271     close(context->fd);
272 OPEN_ERR:
273     free(context);
274     return NULL;
275 }
276 
ResetLiteIpc()277 void ResetLiteIpc()
278 {
279     g_tempHandles = NULL;
280     g_funcPairs = NULL;
281     pthread_mutex_init(&(g_funcPairsMutex), NULL);
282     g_samgrId = 0;
283     g_handle = 0;
284     g_isStartLoop = false;
285     g_tlsContext = NULL;
286     g_tlsReply = NULL;
287     pthread_mutex_init(&(g_ipcCallbackCb.mutex), NULL);
288     g_ipcCallbackCb.handleId = -1;
289     g_ipcCallbackCb.threadWorking = false;
290     InitCallbackCb();
291 }
292 
CloseLiteIpc(IpcContext * context)293 void CloseLiteIpc(IpcContext* context)
294 {
295     if (context == NULL) {
296         return;
297     }
298     munmap(context->mmapAddr, context->mmapSize);
299     close(context->fd);
300     free(context);
301 }
302 
SetSaManager(const IpcContext * context,size_t maxMsgSize)303 int32_t SetSaManager(const IpcContext* context, size_t maxMsgSize)
304 {
305     if (context == NULL) {
306         LOG(ERROR, "Invalid parameter, null pointer.");
307         return LITEIPC_EINTNL;
308     }
309     int ret = ioctl(context->fd, BINDER_SET_CONTEXT_MGR, 0);
310     if (ret == LITEIPC_OK) {
311         g_samgrId = (uint32_t)pthread_self();
312         g_tempHandles = calloc(1, sizeof(UTILS_DL_LIST));
313         if (g_tempHandles == NULL) {
314             LOG(ERROR, "calloc failed.");
315             return LITEIPC_EINTNL;
316         }
317         UtilsListInit(g_tempHandles);
318     }
319     return ret;
320 }
321 
AddServiceAccess(SvcIdentity sid,pid_t pid)322 int32_t AddServiceAccess(SvcIdentity sid, pid_t pid)
323 {
324     (void)sid;
325     (void)pid;
326     return LITEIPC_OK;
327 }
328 
GetCode(const void * ipcMsg,uint32_t * code)329 int32_t GetCode(const void* ipcMsg, uint32_t* code)
330 {
331     if ((ipcMsg == NULL) || (code == NULL)) {
332         LOG(ERROR, "Invalid parameter, null pointer.");
333         return LITEIPC_EINVAL;
334     }
335 
336     const IpcMsg* in = (const IpcMsg*)ipcMsg;
337     *code = in->code;
338     return LITEIPC_OK;
339 }
340 
GetCallingTid(const void * ipcMsg)341 pid_t GetCallingTid(const void* ipcMsg)
342 {
343     if (ipcMsg == NULL) {
344         LOG(ERROR, "Invalid parameter, null pointer.");
345         return LITEIPC_EINVAL;
346     }
347 
348     const IpcMsg* in = (const IpcMsg*)ipcMsg;
349     return (pid_t)in->taskID;
350 }
351 
BinderWrite(const IpcContext * context,void * data,size_t len)352 static int BinderWrite(const IpcContext *context, void *data, size_t len)
353 {
354     struct binder_write_read bwr = {0};
355     int res;
356 
357     bwr.write_size = len;
358     bwr.write_consumed = 0;
359     bwr.write_buffer = (uintptr_t)data;
360     bwr.read_size = 0;
361     bwr.read_consumed = 0;
362     bwr.read_buffer = 0;
363     res = ioctl(context->fd, BINDER_WRITE_READ, &bwr);
364     if (res < 0) {
365         LOG(ERROR, "ioctl failed ret = %d", res);
366     }
367     return res;
368 }
369 
370 static void* BinderThreadRoutine(void *argv);
371 
TxnToIpc(const struct binder_transaction_data * txn,IpcMsg * data)372 static void TxnToIpc(const struct binder_transaction_data *txn, IpcMsg* data)
373 {
374     data->target.handle = txn->target.handle;
375     data->target.token = txn->target.handle;
376     data->code = txn->code;
377     data->flag = txn->flags;
378     data->processID = txn->sender_pid;
379     data->userID = txn->sender_euid;
380     data->dataSz = txn->data_size;
381     data->data = (void *)txn->data.ptr.buffer;
382     data->freeData = (void *)txn->data.ptr.buffer;
383     data->offsets = (void *)txn->data.ptr.offsets;
384     data->spObjNum = txn->offsets_size / sizeof(size_t);
385 }
386 
387 static void TryCallBack(const IpcContext* context, void* msg, IpcIo* data, void* arg);
388 static void GetIpcCallback(IpcMsg* msg, HdlerArg* arg);
389 
IsValidCB(IpcMsg * ipcMsg)390 static bool IsValidCB(IpcMsg* ipcMsg)
391 {
392     HdlerArg tArg = {0};
393     GetIpcCallback(ipcMsg, &tArg);
394     if (tArg.num == 0) {
395         return false;
396     }
397     return true;
398 }
399 
HandleSpawnLooper(const IpcContext * context,const struct FuncPair * funcPair)400 static void HandleSpawnLooper(const IpcContext *context, const struct FuncPair *funcPair)
401 {
402     pthread_t thread;
403     struct BinderThreadDesc *btd = (struct BinderThreadDesc *)malloc(sizeof(struct BinderThreadDesc));
404     if (btd == NULL) {
405         return;
406     }
407     (void)memset_s(btd, sizeof(struct BinderThreadDesc), 0, sizeof(struct BinderThreadDesc));
408 
409     btd->context = context;
410     btd->func = funcPair->func;
411     btd->argv = funcPair->argv;
412     int ret = pthread_create(&thread, NULL, BinderThreadRoutine, btd);
413     if (ret != 0) {
414         free(btd);
415         btd = NULL;
416     }
417 }
418 
HandleTransaction(const IpcContext * context,const struct binder_transaction_data * txn)419 static void HandleTransaction(const IpcContext *context, const struct binder_transaction_data *txn)
420 {
421     IpcMsg *data = (IpcMsg*)calloc(1, sizeof(IpcMsg));
422     if (data == NULL) {
423         LOG(ERROR, "HandleTransaction calloc failed!");
424         return;
425     }
426     data->type = MT_REQUEST;
427     TxnToIpc(txn, data);
428     IpcIo io = {0};
429     IpcIoInitFromMsg(&io, data);
430     uint32_t token = IpcIoPopUint32(&io);
431     SvcIdentity *remote = IpcIoPopSvc(&io);
432     if (remote == NULL) {
433         LOG(ERROR, "HandleTransaction remote NULL!");
434         return;
435     }
436     g_handle = remote->handle;
437     data->data = io.bufferCur;
438     data->offsets = io.offsetsCur;
439     data->dataSz = io.bufferLeft;
440     data->spObjNum = io.offsetsLeft;
441     if (IsValidCB(data)) {
442         TryCallBack(context, data, &io, NULL);
443         free(remote);
444         return;
445     }
446     data->target.token = token;
447     struct FuncPair pair;
448     if (GetFuncPair(&pair, txn->cookie)) {
449         pair.func(context, data, &io, pair.argv);
450     } else if (GetFuncPair(&pair, g_samgrId)) {
451         data->target.handle = remote->handle;
452         pair.func(context, data, &io, pair.argv);
453     } else {
454         LOG(ERROR, "BR_TRANSACTION should not happen!");
455     }
456     free(remote);
457 }
458 
HandleReply(IpcIo * bio,const struct binder_transaction_data * txn,uintptr_t * buffer)459 static void HandleReply(IpcIo* bio, const struct binder_transaction_data *txn, uintptr_t* buffer)
460 {
461     if (bio == NULL) {
462         *buffer = 0;
463         return;
464     }
465     IpcMsg *data = (IpcMsg*)calloc(1, sizeof(IpcMsg));
466     if (data == NULL) {
467         LOG(ERROR, "HandleReply calloc failed!");
468         *buffer = 0;
469         return;
470     }
471 
472     TxnToIpc(txn, data);
473     IpcIoInitFromMsg(bio, data);
474     IpcIoPopUint32(bio);
475     SvcIdentity *sid = IpcIoPopSvc(bio);
476     if (sid != NULL) {
477         free(sid);
478         sid = NULL;
479     }
480     if (buffer != NULL) {
481         *buffer = (uintptr_t)data;
482     }
483 }
484 
HandleDeadBinder(const IpcContext * context,uintptr_t ptr)485 static void HandleDeadBinder(const IpcContext *context, uintptr_t ptr)
486 {
487     struct BinderDeath *death = (struct BinderDeath *)(uintptr_t) *(binder_uintptr_t *)ptr;
488     IpcMsg data = {0};
489     data.type = MT_DEATH_NOTIFY;
490     data.target.token = death->token;
491     data.target.handle = death->token;
492     death->func(context, &data, NULL, NULL);
493 }
494 
BinderRefDone(const IpcContext * context,const struct binder_ptr_cookie * ptrCookie,enum binder_driver_command_protocol cmd)495 static void BinderRefDone(const IpcContext *context, const struct binder_ptr_cookie *ptrCookie,
496                           enum binder_driver_command_protocol cmd)
497 {
498     struct {
499         uint32_t cmd;
500         struct binder_ptr_cookie payload;
501     } __attribute__((packed)) data;
502 
503     data.cmd = cmd;
504     data.payload.ptr = ptrCookie->ptr;
505     data.payload.cookie = ptrCookie->cookie;
506     BinderWrite(context, &data, sizeof(data));
507 }
508 
BinderParse(const IpcContext * context,void * bio,uintptr_t ptr,size_t size,struct FuncPair * funcPair,uintptr_t * buffer)509 static int BinderParse(const IpcContext *context, void *bio, uintptr_t ptr,
510                        size_t size, struct FuncPair *funcPair, uintptr_t* buffer)
511 {
512     int ret = 1;
513     g_tlsContext = context;
514     uintptr_t end = ptr + (uintptr_t) size;
515     while (ptr < end) {
516         uint32_t cmd = *(uint32_t *) ptr;
517         ptr += sizeof(uint32_t);
518         switch (cmd) {
519             case BR_NOOP:
520                 break;
521             case BR_TRANSACTION_COMPLETE:
522                 break;
523             case BR_ACQUIRE: {
524                 struct binder_ptr_cookie *ptrCookie = (struct binder_ptr_cookie *) ptr;
525                 if ((end - ptr) < sizeof(*ptrCookie)) {
526                     return -1;
527                 }
528                 BinderRefDone(context, ptrCookie, BC_ACQUIRE_DONE);
529                 ptr += sizeof(*ptrCookie);
530                 break;
531             }
532             case BR_INCREFS: {
533                 struct binder_ptr_cookie *ptrCookie = (struct binder_ptr_cookie *) ptr;
534                 if ((end - ptr) < sizeof(*ptrCookie)) {
535                     return -1;
536                 }
537                 BinderRefDone(context, ptrCookie, BC_INCREFS_DONE);
538                 ptr += sizeof(*ptrCookie);
539                 break;
540             }
541             case BR_RELEASE:
542             case BR_DECREFS:
543                 ptr += sizeof(struct binder_ptr_cookie);
544                 break;
545             case BR_SPAWN_LOOPER: {
546                 HandleSpawnLooper(context, funcPair);
547                 break;
548             }
549             case BR_TRANSACTION: {
550                 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
551                 if ((end - ptr) < sizeof(*txn)) {
552                     return -1;
553                 }
554                 HandleTransaction(context, txn);
555                 ptr += sizeof(*txn);
556                 break;
557             }
558             case BR_REPLY: {
559                 struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
560                 if ((end - ptr) < sizeof(*txn)) {
561                     return -1;
562                 }
563                 HandleReply(bio, txn, buffer);
564                 ptr += sizeof(*txn);
565                 ret = 0;
566                 break;
567             }
568             case BR_DEAD_BINDER: {
569                 HandleDeadBinder(context, ptr);
570                 ptr += sizeof(binder_uintptr_t);
571                 break;
572             }
573             case BR_FAILED_REPLY:
574                 ret = -1;
575                 break;
576             case BR_DEAD_REPLY:
577                 ret = LITEIPC_DEAD_OBJECT;
578                 break;
579             default:
580                 ret = -1;
581         }
582     }
583     return ret;
584 }
585 
StartLoop(const IpcContext * context,IpcMsgHandler func,void * arg)586 int32_t StartLoop(const IpcContext* context, IpcMsgHandler func, void* arg)
587 {
588     if (context == NULL) {
589         LOG(ERROR, "Invalid parameter, null pointer.");
590         return LITEIPC_EINVAL;
591     }
592     if (g_funcPairs == NULL) {
593         g_funcPairs = calloc(1, sizeof(UTILS_DL_LIST));
594         if (g_funcPairs == NULL) {
595             LOG(ERROR, "Invalid parameter, null pointer.");
596             return LITEIPC_EINVAL;
597         }
598         UtilsListInit(g_funcPairs);
599     }
600     struct binder_write_read bwr = {0};
601     uint32_t readbuf[READ_BUFFER_SIZE] = {0};
602     struct FuncPair funcPair = {0};
603     funcPair.func = func;
604     funcPair.argv = arg;
605     SaveFuncPair(&funcPair);
606 
607     readbuf[0] = BC_ENTER_LOOPER;
608     BinderWrite(context, readbuf, sizeof(uint32_t));
609     for (;;) {
610         bwr.read_size = sizeof(readbuf);
611         bwr.read_consumed = 0;
612         bwr.read_buffer = (uintptr_t) readbuf;
613         int ret = ioctl(context->fd, BINDER_WRITE_READ, &bwr);
614 
615         if (ret < 0) {
616             LOG(ERROR, "ioctl failed ret = %d", ret);
617             break;
618         }
619         ret = BinderParse(context, 0, (uintptr_t)readbuf, bwr.read_consumed, &funcPair, NULL);
620         if (ret == 0) {
621             LOG(ERROR, "reply failed!");
622             break;
623         }
624         if (ret < 0) {
625             LOG(ERROR, "io error %d", ret);
626             break;
627         }
628     }
629 
630     return LITEIPC_OK;
631 }
632 
BinderThreadLoop(const IpcContext * context,IpcMsgHandler func,void * arg)633 static void BinderThreadLoop(const IpcContext* context, IpcMsgHandler func, void* arg)
634 {
635     struct binder_write_read bwr = {0};
636     uint32_t readbuf[READ_BUFFER_SIZE] = {0};
637     struct FuncPair funcPair = {0};
638     funcPair.func = func;
639     funcPair.argv = arg;
640 
641     readbuf[0] = BC_REGISTER_LOOPER;
642 
643     BinderWrite(context, readbuf, sizeof(uint32_t));
644     for (;;) {
645         bwr.read_size = sizeof(readbuf);
646         bwr.read_consumed = 0;
647         bwr.read_buffer = (uintptr_t) readbuf;
648         int ret = ioctl(context->fd, BINDER_WRITE_READ, &bwr);
649 
650         if (ret < 0) {
651             LOG(ERROR, "ioctl failed ret = %d", ret);
652             break;
653         }
654         ret = BinderParse(context, 0, (uintptr_t)readbuf, bwr.read_consumed, &funcPair, NULL);
655         if (ret == 0) {
656             LOG(ERROR, "reply failed");
657             break;
658         }
659         if (ret < 0) {
660             LOG(ERROR, "io error ret = %d", ret);
661             break;
662         }
663     }
664 }
665 
BinderThreadRoutine(void * argv)666 static void* BinderThreadRoutine(void *argv)
667 {
668     struct BinderThreadDesc *btd = (struct BinderThreadDesc *)argv;
669     BinderThreadLoop(btd->context, btd->func, btd->argv);
670     free(argv);
671     argv = NULL;
672     return NULL;
673 }
674 
ToTransData(SvcIdentity sid,uint32_t code,IpcIo * data,IpcFlag flag,struct TransactData * buf)675 static void ToTransData(SvcIdentity sid, uint32_t code, IpcIo* data, IpcFlag flag, struct TransactData *buf)
676 {
677     buf->btd.target.ptr = 0;
678     buf->btd.target.handle = sid.handle;
679     buf->btd.code = code;
680     buf->btd.flags = flag;
681     buf->btd.cookie = 0;
682     buf->btd.sender_pid = getpid();
683     buf->btd.sender_euid = getuid();
684     if ((data != NULL) && (data->bufferBase != NULL)) {
685         (data->bufferBase)[0] = sid.token;
686     }
687     buf->btd.data_size = (data == NULL) ? 0 : (data->bufferCur - data->bufferBase);
688     buf->btd.data.ptr.buffer = (data == NULL) ? 0 : (binder_uintptr_t)data->bufferBase;
689     buf->btd.offsets_size = (data == NULL) ? 0 : ((char*)data->offsetsCur - (char*)data->offsetsBase);
690     buf->btd.offsets_size = IPC_IO_ALIGN(buf->btd.offsets_size);
691     buf->btd.data.ptr.offsets = (data == NULL) ? 0 : (binder_uintptr_t)data->offsetsBase;
692 }
693 
GetIpcContext(const IpcContext * context,const IpcContext * tlsContext)694 static IpcContext* GetIpcContext(const IpcContext* context, const IpcContext* tlsContext)
695 {
696     const IpcContext *tmpContext = NULL;
697     if (tlsContext != NULL) {
698         tmpContext = tlsContext;
699     } else if (context != NULL) {
700         tmpContext = context;
701     }
702     return (IpcContext*)tmpContext;
703 }
704 
HandleInternelRequest(const IpcContext * context,SvcIdentity sid,uint32_t code,IpcIo * data,IpcIo * reply,IpcFlag flag)705 static int32_t HandleInternelRequest(const IpcContext *context, SvcIdentity sid, uint32_t code,
706                                      IpcIo* data, IpcIo* reply, IpcFlag flag)
707 {
708     AnonymousApi* node = (AnonymousApi*)sid.token;
709     if (node == NULL) {
710         LOG(ERROR, "Invalid parameter, node null pointer.");
711         return LITEIPC_EINVAL;
712     }
713     IpcMsg msg = {
714         .type = MT_REQUEST,
715         .target = sid,
716         .code = code,
717         .flag = flag,
718         .dataSz = (data == NULL) ? 0 : (data->bufferCur - data->bufferBase),
719         .data = (data == NULL) ? NULL : data->bufferBase,
720         .offsets = (data == NULL) ? NULL : data->offsetsBase,
721         .spObjNum = (data == NULL) ? 0 : ((char*)data->offsetsCur - (char*)data->offsetsBase) / sizeof(size_t)
722     };
723     IpcIo tmp;
724     IpcIoInitFromMsg(&tmp, &msg);
725     IpcIoPopUint32(&tmp);
726     SvcIdentity *sidTmp = IpcIoPopSvc(&tmp);
727     if (sidTmp != NULL) {
728         free(sidTmp);
729         sidTmp = NULL;
730     }
731     msg.data = tmp.bufferCur;
732     msg.offsets = tmp.offsetsCur;
733     msg.dataSz = tmp.bufferLeft;
734     msg.spObjNum = tmp.offsetsLeft;
735     if (reply != NULL) {
736         g_tlsReply = &reply;
737     }
738     node->hdlerPair.hdler(context, &msg, &tmp, node->hdlerPair.arg);
739     return LITEIPC_OK;
740 }
741 
SendRequest(const IpcContext * context,SvcIdentity sid,uint32_t code,IpcIo * data,IpcIo * reply,IpcFlag flag,uintptr_t * buffer)742 int32_t SendRequest(const IpcContext *context, SvcIdentity sid, uint32_t code,
743                     IpcIo* data, IpcIo* reply, IpcFlag flag, uintptr_t* buffer)
744 {
745     const IpcContext *tmpContext = GetIpcContext(context, sid.ipcContext);
746     if (tmpContext == NULL) {
747         LOG(ERROR, "Invalid parameter, null pointer.");
748         return LITEIPC_EINVAL;
749     }
750     if ((flag > LITEIPC_FLAG_ONEWAY) || ((flag == LITEIPC_FLAG_DEFAULT) && (buffer == NULL))) {
751         LOG(ERROR, "Invalid parameter, null pointer.");
752         return LITEIPC_EINVAL;
753     }
754 
755     if (sid.handle == MIN_BINDER_HANDLE) {
756         return HandleInternelRequest(tmpContext, sid, code, data, reply, flag);
757     }
758     int ret;
759     if (!g_isStartLoop) {
760         ret = StartCallbackDispatch(tmpContext);
761         if (ret != LITEIPC_OK) {
762             LOG(ERROR, "StartCallbackDispatch failed.");
763         }
764     }
765     struct TransactData buf;
766     struct binder_write_read bwr;
767     ret = CheckIpcIo(data);
768     if (ret != LITEIPC_OK) {
769         LOG(ERROR, "CheckIpcIo failed.");
770         return ret;
771     }
772     buf.cmd = BC_TRANSACTION;
773     IpcIo tempIo;
774     if (data == NULL) {
775         data = &tempIo;
776         uint8_t tmpData[IPC_IO_DATA_TEMP];
777         IpcIoInit(data, tmpData, IPC_IO_DATA_TEMP, 0);
778     }
779     ToTransData(sid, code, data, flag, &buf);
780     bwr.write_size = sizeof(buf);
781     bwr.write_consumed = 0;
782     bwr.write_buffer = (uintptr_t)&buf;
783     uint32_t readbuf[READ_BUFFER_SIZE] = {0};
784     if (flag != LITEIPC_FLAG_ONEWAY) {
785         while (1) {
786             bwr.read_size = sizeof(readbuf);
787             bwr.read_consumed = 0;
788             bwr.read_buffer = (uintptr_t)readbuf;
789             ioctl(tmpContext->fd, BINDER_WRITE_READ, &bwr);
790             ret = BinderParse(tmpContext, reply, (uintptr_t)readbuf, bwr.read_consumed, NULL, buffer);
791             if (ret == 0) {
792                 break;
793             }
794         }
795     } else {
796         bwr.read_size = sizeof(readbuf);
797         bwr.read_consumed = 0;
798         bwr.read_buffer = (uintptr_t)readbuf;
799         ioctl(tmpContext->fd, BINDER_WRITE_READ, &bwr);
800         ret = BinderParse(tmpContext, reply, (uintptr_t)readbuf, bwr.read_consumed, NULL, NULL);
801         if (ret == 1) {
802             ret = 0;
803         }
804     }
805     return ret;
806 }
807 
SendReply(const IpcContext * context,void * ipcMsg,IpcIo * reply)808 int32_t SendReply(const IpcContext* context, void* ipcMsg, IpcIo* reply)
809 {
810     const IpcContext *tmpContext = NULL;
811     if (context != NULL) {
812         tmpContext = context;
813     } else if (g_tlsContext != NULL) {
814         tmpContext = g_tlsContext;
815     } else {
816         LOG(ERROR, "Invalid parameter, null pointer.");
817         return LITEIPC_EINVAL;
818     }
819     (void)FreeBuffer(tmpContext, ipcMsg);
820 
821     int32_t ret = CheckIpcIo(reply);
822     if (ret != LITEIPC_OK) {
823         LOG(ERROR, "CheckIpcIo failed.");
824         return ret;
825     }
826 
827     if (g_tlsReply != NULL && *g_tlsReply != NULL) {
828         IpcIo tmp;
829         IpcMsg msg = {
830             .dataSz = (reply == NULL) ? 0 : (reply->bufferCur - reply->bufferBase),
831             .data = (reply == NULL) ? NULL : (void*)reply->bufferBase,
832             .offsets = (reply == NULL) ? NULL : reply->offsetsBase,
833             .spObjNum = (reply == NULL) ? 0 : ((char*)reply->offsetsCur - (char*)reply->offsetsBase) / sizeof(size_t)
834         };
835         IpcIoInitFromMsg(&tmp, &msg);
836 
837         size_t objectsSize = tmp.offsetsLeft * sizeof(size_t);
838         (*g_tlsReply)->bufferCur = (*g_tlsReply)->bufferBase = (char*)g_tlsReplyData + objectsSize;
839         (*g_tlsReply)->offsetsCur = (*g_tlsReply)->offsetsBase = (size_t*)g_tlsReplyData;
840         memcpy_s((*g_tlsReply)->bufferBase, IPC_IO_DATA_MAX, tmp.bufferBase, tmp.bufferLeft);
841         memcpy_s((*g_tlsReply)->offsetsBase, objectsSize, tmp.offsetsBase, objectsSize);
842         (*g_tlsReply)->bufferLeft = tmp.bufferLeft;
843         (*g_tlsReply)->offsetsLeft = tmp.offsetsLeft;
844         (*g_tlsReply)->flag = reply->flag;
845 
846         IpcIoPopUint32(*g_tlsReply);
847         SvcIdentity *sid = IpcIoPopSvc(*g_tlsReply);
848         if (sid != NULL) {
849             free(sid);
850             sid = NULL;
851         }
852         g_tlsReply = NULL;
853         return LITEIPC_OK;
854     }
855 
856     struct TransactData buf = {0};
857     buf.cmd = BC_REPLY;
858     SvcIdentity sid = {0};
859     IpcIo tempIo;
860     if (reply == NULL) {
861         reply = &tempIo;
862         uint8_t tmpData[IPC_IO_DATA_TEMP];
863         IpcIoInit(reply, tmpData, IPC_IO_DATA_TEMP, 0);
864     }
865     ToTransData(sid, 0, reply, 0, &buf);
866     ret = BinderWrite(tmpContext, &buf, sizeof(buf));
867     return ret;
868 }
869 
CallbackBatchHandler(void * arg)870 static void CallbackBatchHandler(void* arg)
871 {
872     HdlerArg* hdlerArg = (HdlerArg*)arg;
873     IpcMsg* msg = hdlerArg->msg;
874     uint32_t i;
875 
876     for (i = 0; i < hdlerArg->num; i++) {
877         if (hdlerArg->cbs[i].usedFlag == true) {
878             (hdlerArg->cbs[i].hdler)(hdlerArg->context, hdlerArg->msg, &hdlerArg->io, hdlerArg->cbs[i].arg);
879         }
880     }
881     if (msg->type == MT_DEATH_NOTIFY) {
882         RemoveDeathCallback(msg->target.token);
883         FreeBuffer(NULL, msg);
884     }
885     free(arg);
886     return;
887 }
888 
GetIpcCallback(IpcMsg * msg,HdlerArg * arg)889 static void GetIpcCallback(IpcMsg* msg, HdlerArg* arg)
890 {
891     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
892         LOG(ERROR, "Get callback mutex failed.");
893         return;
894     }
895     IpcIoInitFromMsg(&arg->io, msg);
896     arg->msg = msg;
897 
898     AnonymousApi* node = NULL;
899     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_ipcCallbackCb.apis, AnonymousApi, list)
900     {
901         if (node->token == msg->target.token) {
902             arg->num = 1;
903             arg->cbs = &node->hdlerPair;
904             (void)pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
905             return;
906         }
907     }
908     arg->num = 0;
909     arg->cbs = NULL;
910     (void)pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
911 }
912 
GetDeathCallback(IpcMsg * msg,HdlerArg * arg)913 static void GetDeathCallback(IpcMsg* msg, HdlerArg* arg)
914 {
915     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
916         LOG(ERROR, "Get callback mutex failed.");
917         return;
918     }
919     IpcIoInitFromMsg(&arg->io, msg);
920     arg->msg = msg;
921 
922     Testament* node = NULL;
923     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_ipcCallbackCb.testaments, Testament, list)
924     {
925         if (node->handle == msg->target.token) {
926             node->isCallbackRuning = true;
927             arg->num = MAX_DEATHCB_PER_SVC;
928             arg->cbs = node->hdlerPairs;
929             (void)pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
930             return;
931         }
932     }
933     arg->num = 0;
934     arg->cbs = NULL;
935     (void)pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
936 }
937 
TryCallBack(const IpcContext * context,void * msg,IpcIo * data,void * arg)938 static void TryCallBack(const IpcContext* context, void* msg, IpcIo* data, void* arg)
939 {
940     IpcMsg* ipcMsg = (IpcMsg *)msg;
941     HdlerArg* tArg = (HdlerArg*)malloc(sizeof(HdlerArg));
942     if (tArg == NULL) {
943         goto ERROR_MALLOC;
944     }
945 
946     switch (ipcMsg->type) {
947         case MT_DEATH_NOTIFY:
948             GetDeathCallback(ipcMsg, tArg);
949             break;
950         case MT_REQUEST:
951             GetIpcCallback(ipcMsg, tArg);
952             break;
953         default:
954             LOG(ERROR, "Callback thread received an unrecognized message.(type=%d)", ipcMsg->type);
955             goto ERROR_MSG;
956     }
957 
958     if (tArg->num == 0) {
959         goto ERROR_MSG;
960     }
961     tArg->context = context;
962     CallbackBatchHandler(tArg);
963     return;
964 ERROR_MSG:
965     free(tArg);
966 ERROR_MALLOC:
967     if ((ipcMsg->type == MT_REQUEST) && (ipcMsg->flag == LITEIPC_FLAG_DEFAULT)) {
968         SendReply(context, ipcMsg, data);
969     } else {
970         (void)FreeBuffer(context, ipcMsg);
971     }
972 }
973 
CallbackDispatch(void * arg)974 static void* CallbackDispatch(void* arg)
975 {
976     IpcContext *ipcContext = (IpcContext*)arg;
977     if (ipcContext == NULL) {
978         return (void*)(intptr_t)LITEIPC_EINTNL;
979     }
980     g_ipcCallbackCb.threadWorking = true;
981     StartLoop(ipcContext, (IpcMsgHandler)TryCallBack, NULL);
982     return (void*)(intptr_t)LITEIPC_OK;
983 }
984 
StartCallbackDispatch(const IpcContext * context)985 static int32_t StartCallbackDispatch(const IpcContext *context)
986 {
987     g_isStartLoop = true;
988     pthread_attr_t threadAttr;
989     pthread_attr_init(&threadAttr);
990     pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
991     pthread_t tid;
992     int32_t ret = pthread_create(&tid, &threadAttr, CallbackDispatch, (void *)context);
993     if (ret != 0) {
994         LOG(ERROR, "Create callback dispatch thread failed.");
995         g_isStartLoop = false;
996         return LITEIPC_EINTNL;
997     }
998     struct timespec spark, now;
999     clock_gettime(CLOCK_REALTIME, &spark);
1000     sched_yield();
1001     while (!g_ipcCallbackCb.threadWorking) {
1002         clock_gettime(CLOCK_REALTIME, &now);
1003         if (now.tv_sec - spark.tv_sec > 1) {
1004             LOG(ERROR, "Wait callback thread starting timeout.");
1005             return LITEIPC_EINTNL;
1006         }
1007         sched_yield();
1008     }
1009     return LITEIPC_OK;
1010 }
1011 
RegisterIpcCallback(IpcMsgHandler func,uint32_t mode,uint32_t timeoutMs,SvcIdentity * sid,void * arg)1012 int32_t RegisterIpcCallback(IpcMsgHandler func, uint32_t mode, uint32_t timeoutMs, SvcIdentity* sid, void* arg)
1013 {
1014     if (g_init == 0) {
1015         InitCallbackCb();
1016     }
1017     if ((func == NULL) || (sid == NULL) || (mode > RESET_AFTER_USE) || (timeoutMs < IPC_TIMEOUT_MIN)) {
1018         return LITEIPC_EINVAL;
1019     }
1020 
1021     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
1022         LOG(ERROR, "Get callback mutex failed.");
1023         return LITEIPC_EINTNL;
1024     }
1025 
1026     int ret = LITEIPC_OK;
1027     AnonymousApi* node = (AnonymousApi*)malloc(sizeof(AnonymousApi));
1028     if (node == NULL) {
1029         LOG(ERROR, "Malloc failed.(size=%zu)", sizeof(AnonymousApi));
1030         ret = LITEIPC_EINTNL;
1031         goto ERROR;
1032     }
1033     (void)memset_s(node, sizeof(AnonymousApi), 0, sizeof(AnonymousApi));
1034 
1035     node->token = (uint32_t)(uintptr_t)node;
1036     node->hdlerPair.usedFlag = true;
1037     node->hdlerPair.hdler = func;
1038     node->hdlerPair.arg = arg;
1039     UtilsListAdd(&g_ipcCallbackCb.apis, &node->list);
1040     sid->token = node->token;
1041     sid->handle = 0;
1042     sid->cookie = node->token;
1043 ERROR:
1044     pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1045     return ret;
1046 }
1047 
UnregisterIpcCallback(SvcIdentity sid)1048 int32_t UnregisterIpcCallback(SvcIdentity sid)
1049 {
1050     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
1051         LOG(ERROR, "Get callback mutex failed.");
1052         return LITEIPC_EINTNL;
1053     }
1054 
1055     AnonymousApi* node = NULL;
1056     AnonymousApi* next = NULL;
1057     UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, &g_ipcCallbackCb.apis, AnonymousApi, list)
1058     {
1059         if (node->token == sid.token) {
1060             UtilsListDelete(&node->list);
1061             free(node);
1062             pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1063             return LITEIPC_OK;
1064         }
1065     }
1066 
1067     LOG(ERROR, "Input sid not exist.");
1068     pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1069 
1070     return LITEIPC_OK;
1071 }
1072 
SetDeathHandlerPair(Testament * node,uint32_t index,IpcMsgHandler func,void * arg)1073 static inline uint32_t SetDeathHandlerPair(Testament* node, uint32_t index, IpcMsgHandler func, void* arg)
1074 {
1075     node->hdlerPairs[index].usedFlag = true;
1076     node->hdlerPairs[index].hdler = func;
1077     node->hdlerPairs[index].arg = arg;
1078     return index;
1079 }
1080 
BinderLinkToDeath(const SvcIdentity * sid,IpcMsgHandler callback,const IpcContext * context)1081 static void BinderLinkToDeath(const SvcIdentity *sid, IpcMsgHandler callback, const IpcContext* context)
1082 {
1083     struct BinderDeath *bd;
1084     struct {
1085         uint32_t cmd;
1086         struct binder_handle_cookie payload;
1087     } __attribute__((packed)) data;
1088     bd = calloc(1, sizeof(struct BinderDeath));
1089     if (bd == NULL) {
1090         return;
1091     }
1092     bd->func = (void *)callback;
1093     bd->token = sid->handle;
1094     data.cmd = BC_REQUEST_DEATH_NOTIFICATION;
1095     data.payload.handle = sid->handle;
1096     data.payload.cookie = (binder_uintptr_t)bd;
1097     BinderWrite(context, &data, sizeof(data));
1098 }
1099 
RegisterDeathCallback(const IpcContext * context,SvcIdentity sid,IpcMsgHandler func,void * arg,uint32_t * cbId)1100 int32_t RegisterDeathCallback(const IpcContext* context, SvcIdentity sid, IpcMsgHandler func, void* arg, uint32_t* cbId)
1101 {
1102     int ret = LITEIPC_OK;
1103     Testament* node = NULL;
1104 
1105     if ((func == NULL) || (cbId == NULL)) {
1106         return LITEIPC_EINVAL;
1107     }
1108 
1109     const IpcContext *tmpContext = GetIpcContext(context, sid.ipcContext);
1110     if (tmpContext == NULL) {
1111         LOG(ERROR, "Invalid parameter, null pointer.");
1112         return LITEIPC_EINVAL;
1113     }
1114 
1115     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
1116         LOG(ERROR, "Get callback mutex failed.");
1117         return LITEIPC_EINTNL;
1118     }
1119 
1120     UTILS_DL_LIST_FOR_EACH_ENTRY(node, &g_ipcCallbackCb.testaments, Testament, list)
1121     {
1122         if (node->handle != sid.handle) {
1123             continue;
1124         }
1125 
1126         if (node->size == MAX_DEATHCB_PER_SVC) {
1127             LOG(ERROR, "Reach max num on this svc:%d", sid.handle);
1128             ret = LITEIPC_EINTNL;
1129             goto UNLOCK_RETURN;
1130         }
1131         for (int i = 0; i < MAX_DEATHCB_PER_SVC; i++) {
1132             if (node->hdlerPairs[i].usedFlag == false) {
1133                 node->size++;
1134                 *cbId = SetDeathHandlerPair(node, i, func, arg);
1135                 break;
1136             }
1137         }
1138         goto UNLOCK_RETURN;
1139     }
1140     node = (Testament*)malloc(sizeof(Testament));
1141     if (node == NULL) {
1142         LOG(ERROR, "Malloc failed.(size=%zu)", sizeof(Testament));
1143         ret = LITEIPC_ENOMEM;
1144         goto UNLOCK_RETURN;
1145     }
1146     (void)memset_s(node, sizeof(Testament), 0, sizeof(Testament));
1147     node->handle = sid.handle;
1148     node->size = 1;
1149     *cbId = SetDeathHandlerPair(node, 0, func, arg);
1150     UtilsListAdd(&g_ipcCallbackCb.testaments, &node->list);
1151     BinderLinkToDeath(&sid, (IpcMsgHandler)TryCallBack, tmpContext);
1152 
1153 UNLOCK_RETURN:
1154     pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1155     return ret;
1156 }
1157 
UnregisterDeathCallback(SvcIdentity sid,uint32_t cbId)1158 int32_t UnregisterDeathCallback(SvcIdentity sid, uint32_t cbId)
1159 {
1160     Testament* node = NULL;
1161     Testament* next = NULL;
1162     if (cbId >= MAX_DEATHCB_PER_SVC) {
1163         LOG(ERROR, "Wrong cbId:%d.", cbId);
1164         return LITEIPC_EINVAL;
1165     }
1166     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
1167         LOG(ERROR, "Get callback mutex failed.");
1168         return LITEIPC_EINTNL;
1169     }
1170     UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, &g_ipcCallbackCb.testaments, Testament, list)
1171     {
1172         if (node->handle == sid.handle) {
1173             if ((node->isCallbackRuning == false) && (node->hdlerPairs[cbId].usedFlag == true)) {
1174                 node->hdlerPairs[cbId].usedFlag = false;
1175                 node->size--;
1176                 if (node->size == 0) {
1177                     UtilsListDelete(&node->list);
1178                     free(node);
1179                 }
1180             }
1181             pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1182             return LITEIPC_OK;
1183         }
1184     }
1185     LOG(ERROR, "Input sid not exist.");
1186     pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1187 
1188     return LITEIPC_OK;
1189 }
1190 
RemoveDeathCallback(uint32_t handle)1191 static void RemoveDeathCallback(uint32_t handle)
1192 {
1193     Testament* node = NULL;
1194     Testament* next = NULL;
1195 
1196     if (pthread_mutex_lock(&g_ipcCallbackCb.mutex) != 0) {
1197         LOG(ERROR, "Get callback mutex failed.");
1198         return;
1199     }
1200     UTILS_DL_LIST_FOR_EACH_ENTRY_SAFE(node, next, &g_ipcCallbackCb.testaments, Testament, list)
1201     {
1202         if (node->handle == handle) {
1203             UtilsListDelete(&node->list);
1204             free(node);
1205             break;
1206         }
1207     }
1208     pthread_mutex_unlock(&g_ipcCallbackCb.mutex);
1209 }
1210 
GetToken(const void * ipcMsg,uint32_t * token)1211 int32_t GetToken(const void* ipcMsg, uint32_t* token)
1212 {
1213     if ((ipcMsg == NULL) || (token == NULL)) {
1214         LOG(ERROR, "Invalid parameter, null pointer.");
1215         return LITEIPC_EINVAL;
1216     }
1217 
1218     const IpcMsg* in = (const IpcMsg*)ipcMsg;
1219     *token = in->target.token;
1220     return LITEIPC_OK;
1221 }
1222 
GetFlag(const void * ipcMsg,uint32_t * flag)1223 int32_t GetFlag(const void* ipcMsg, uint32_t* flag)
1224 {
1225     if ((ipcMsg == NULL) || (flag == NULL)) {
1226         LOG(ERROR, "Invalid parameter, null pointer.");
1227         return LITEIPC_EINVAL;
1228     }
1229 
1230     const IpcMsg* in = (const IpcMsg*)ipcMsg;
1231     *flag = in->flag;
1232     return LITEIPC_OK;
1233 }
1234 
GetCallingPid(const void * ipcMsg)1235 pid_t GetCallingPid(const void* ipcMsg)
1236 {
1237     if (ipcMsg == NULL) {
1238         LOG(ERROR, "Invalid parameter, null pointer.");
1239         return LITEIPC_EINVAL;
1240     }
1241 
1242     const IpcMsg* in = (const IpcMsg*)ipcMsg;
1243     return (pid_t)in->processID;
1244 }
1245 
GetCallingUid(const void * ipcMsg)1246 pid_t GetCallingUid(const void* ipcMsg)
1247 {
1248     if (ipcMsg == NULL) {
1249         LOG(ERROR, "Invalid parameter, null pointer.");
1250         return LITEIPC_EINVAL;
1251     }
1252 
1253     const IpcMsg* in = (const IpcMsg*)ipcMsg;
1254     return (pid_t)in->userID;
1255 }
1256 
GetCallingGid(const void * ipcMsg)1257 pid_t GetCallingGid(const void* ipcMsg)
1258 {
1259     if (ipcMsg == NULL) {
1260         LOG(ERROR, "Invalid parameter, null pointer.");
1261         return LITEIPC_EINVAL;
1262     }
1263 
1264     const IpcMsg* in = (const IpcMsg*)ipcMsg;
1265     return (pid_t)in->gid;
1266 }
1267 
FreeBuffer(const IpcContext * context,void * ptr)1268 int32_t FreeBuffer(const IpcContext* context, void* ptr)
1269 {
1270     if (ptr == NULL) {
1271         return LITEIPC_OK;
1272     }
1273 
1274     IpcMsg* ipcMsg = (IpcMsg*)ptr;
1275     if (ipcMsg->freeData == NULL) {
1276         return LITEIPC_OK;
1277     }
1278 
1279     const IpcContext *tmpContext = GetIpcContext(context, g_tlsContext);
1280     if (tmpContext == NULL) {
1281         LOG(ERROR, "Invalid parameter, null pointer.");
1282         free(ptr);
1283         ptr = NULL;
1284         return LITEIPC_EINTNL;
1285     }
1286     struct FreeData data = {0};
1287     data.cmd = BC_FREE_BUFFER;
1288     data.buffer = (binder_uintptr_t)ipcMsg->freeData;
1289     int ret = BinderWrite(tmpContext, &data, sizeof(data));
1290     free(ptr);
1291     ptr = NULL;
1292     RETURN_IF_IPC_IOCTL_FAILED(LITEIPC_EBADF);
1293     return ret;
1294 }
1295 
GenServiceHandle(SvcIdentity * sid,pid_t tid)1296 int32_t GenServiceHandle(SvcIdentity* sid, pid_t tid)
1297 {
1298     if (g_tempHandles == NULL || sid == NULL) {
1299         return LITEIPC_EINVAL;
1300     }
1301     sid->handle = g_handle;
1302     return LITEIPC_OK;
1303 }
1304 
BinderAcquire(const IpcContext * context,uint32_t handle)1305 int32_t BinderAcquire(const IpcContext* context, uint32_t handle)
1306 {
1307     if (context == NULL) {
1308         return LITEIPC_EINVAL;
1309     }
1310     uint32_t cmd[2];
1311     cmd[0] = BC_ACQUIRE;
1312     cmd[1] = handle;
1313     int ret;
1314     ret = BinderWrite(context, &cmd, sizeof(cmd));
1315     return ret;
1316 }
1317 
BinderRelease(const IpcContext * context,uint32_t handle)1318 int32_t BinderRelease(const IpcContext* context, uint32_t handle)
1319 {
1320     if (context == NULL) {
1321         return LITEIPC_EINVAL;
1322     }
1323     uint32_t cmd[2];
1324     cmd[0] = BC_RELEASE;
1325     cmd[1] = handle;
1326     int ret;
1327     ret = BinderWrite(context, &cmd, sizeof(cmd));
1328     return ret;
1329 }
1330