10d163575Sopenharmony_ci/*
20d163575Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
30d163575Sopenharmony_ci * Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
40d163575Sopenharmony_ci *
50d163575Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification,
60d163575Sopenharmony_ci * are permitted provided that the following conditions are met:
70d163575Sopenharmony_ci *
80d163575Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of
90d163575Sopenharmony_ci *    conditions and the following disclaimer.
100d163575Sopenharmony_ci *
110d163575Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list
120d163575Sopenharmony_ci *    of conditions and the following disclaimer in the documentation and/or other materials
130d163575Sopenharmony_ci *    provided with the distribution.
140d163575Sopenharmony_ci *
150d163575Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used
160d163575Sopenharmony_ci *    to endorse or promote products derived from this software without specific prior written
170d163575Sopenharmony_ci *    permission.
180d163575Sopenharmony_ci *
190d163575Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
200d163575Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
210d163575Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
220d163575Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
230d163575Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
240d163575Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
250d163575Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
260d163575Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
270d163575Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
280d163575Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
290d163575Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
300d163575Sopenharmony_ci */
310d163575Sopenharmony_ci
320d163575Sopenharmony_ci#include "hm_liteipc.h"
330d163575Sopenharmony_ci#include "linux/kernel.h"
340d163575Sopenharmony_ci#include "fs/file.h"
350d163575Sopenharmony_ci#include "fs/driver.h"
360d163575Sopenharmony_ci#include "los_init.h"
370d163575Sopenharmony_ci#include "los_mp.h"
380d163575Sopenharmony_ci#include "los_mux.h"
390d163575Sopenharmony_ci#include "los_process_pri.h"
400d163575Sopenharmony_ci#include "los_sched_pri.h"
410d163575Sopenharmony_ci#include "los_spinlock.h"
420d163575Sopenharmony_ci#include "los_task_pri.h"
430d163575Sopenharmony_ci#include "los_vm_lock.h"
440d163575Sopenharmony_ci#include "los_vm_map.h"
450d163575Sopenharmony_ci#include "los_vm_page.h"
460d163575Sopenharmony_ci#include "los_vm_phys.h"
470d163575Sopenharmony_ci#include "los_hook.h"
480d163575Sopenharmony_ci
490d163575Sopenharmony_ci#define USE_TASKID_AS_HANDLE 1
500d163575Sopenharmony_ci#define USE_MMAP 1
510d163575Sopenharmony_ci#define IPC_IO_DATA_MAX 8192UL
520d163575Sopenharmony_ci#define IPC_MSG_DATA_SZ_MAX (IPC_IO_DATA_MAX * sizeof(SpecialObj) / (sizeof(SpecialObj) + sizeof(size_t)))
530d163575Sopenharmony_ci#define IPC_MSG_OBJECT_NUM_MAX (IPC_MSG_DATA_SZ_MAX / sizeof(SpecialObj))
540d163575Sopenharmony_ci
550d163575Sopenharmony_ci#define LITE_IPC_POOL_NAME "liteipc"
560d163575Sopenharmony_ci#define LITE_IPC_POOL_PAGE_MAX_NUM 64 /* 256KB */
570d163575Sopenharmony_ci#define LITE_IPC_POOL_PAGE_DEFAULT_NUM 16 /* 64KB */
580d163575Sopenharmony_ci#define LITE_IPC_POOL_MAX_SIZE (LITE_IPC_POOL_PAGE_MAX_NUM << PAGE_SHIFT)
590d163575Sopenharmony_ci#define LITE_IPC_POOL_DEFAULT_SIZE (LITE_IPC_POOL_PAGE_DEFAULT_NUM << PAGE_SHIFT)
600d163575Sopenharmony_ci#define LITE_IPC_POOL_UVADDR 0x10000000
610d163575Sopenharmony_ci#define INVAILD_ID (-1)
620d163575Sopenharmony_ci
630d163575Sopenharmony_ci#define LITEIPC_TIMEOUT_MS 5000UL
640d163575Sopenharmony_ci#define LITEIPC_TIMEOUT_NS 5000000000ULL
650d163575Sopenharmony_ci
660d163575Sopenharmony_ci#define MAJOR_VERSION (2)
670d163575Sopenharmony_ci#define MINOR_VERSION (0)
680d163575Sopenharmony_ci#define DRIVER_VERSION (MAJOR_VERSION | MINOR_VERSION << 16)
690d163575Sopenharmony_ci
700d163575Sopenharmony_citypedef struct {
710d163575Sopenharmony_ci    LOS_DL_LIST list;
720d163575Sopenharmony_ci    VOID *ptr;
730d163575Sopenharmony_ci} IpcUsedNode;
740d163575Sopenharmony_ci
750d163575Sopenharmony_ciSTATIC LosMux g_serviceHandleMapMux;
760d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
770d163575Sopenharmony_ciSTATIC HandleInfo g_cmsTask;
780d163575Sopenharmony_ci#else
790d163575Sopenharmony_ciSTATIC HandleInfo g_serviceHandleMap[MAX_SERVICE_NUM];
800d163575Sopenharmony_ci#endif
810d163575Sopenharmony_ciSTATIC LOS_DL_LIST g_ipcPendlist;
820d163575Sopenharmony_ci
830d163575Sopenharmony_ci/* ipc lock */
840d163575Sopenharmony_ciSPIN_LOCK_INIT(g_ipcSpin);
850d163575Sopenharmony_ci#define IPC_LOCK(state)       LOS_SpinLockSave(&g_ipcSpin, &(state))
860d163575Sopenharmony_ci#define IPC_UNLOCK(state)     LOS_SpinUnlockRestore(&g_ipcSpin, state)
870d163575Sopenharmony_ci
880d163575Sopenharmony_ciSTATIC int LiteIpcOpen(struct file *filep);
890d163575Sopenharmony_ciSTATIC int LiteIpcClose(struct file *filep);
900d163575Sopenharmony_ciSTATIC int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg);
910d163575Sopenharmony_ciSTATIC int LiteIpcMmap(struct file* filep, LosVmMapRegion *region);
920d163575Sopenharmony_ciSTATIC UINT32 LiteIpcWrite(IpcContent *content);
930d163575Sopenharmony_ciSTATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID);
940d163575Sopenharmony_ciSTATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback);
950d163575Sopenharmony_ciSTATIC ProcIpcInfo *LiteIpcPoolCreate(VOID);
960d163575Sopenharmony_ci
970d163575Sopenharmony_ciSTATIC const struct file_operations_vfs g_liteIpcFops = {
980d163575Sopenharmony_ci    .open = LiteIpcOpen,   /* open */
990d163575Sopenharmony_ci    .close = LiteIpcClose,  /* close */
1000d163575Sopenharmony_ci    .ioctl = LiteIpcIoctl,  /* ioctl */
1010d163575Sopenharmony_ci    .mmap = LiteIpcMmap,   /* mmap */
1020d163575Sopenharmony_ci};
1030d163575Sopenharmony_ci
1040d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT UINT32 OsLiteIpcInit(VOID)
1050d163575Sopenharmony_ci{
1060d163575Sopenharmony_ci    UINT32 ret;
1070d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
1080d163575Sopenharmony_ci    g_cmsTask.status = HANDLE_NOT_USED;
1090d163575Sopenharmony_ci#else
1100d163575Sopenharmony_ci    (void)memset_s(g_serviceHandleMap, sizeof(g_serviceHandleMap), 0, sizeof(g_serviceHandleMap));
1110d163575Sopenharmony_ci#endif
1120d163575Sopenharmony_ci    ret = LOS_MuxInit(&g_serviceHandleMapMux, NULL);
1130d163575Sopenharmony_ci    if (ret != LOS_OK) {
1140d163575Sopenharmony_ci        return ret;
1150d163575Sopenharmony_ci    }
1160d163575Sopenharmony_ci    ret = (UINT32)register_driver(LITEIPC_DRIVER, &g_liteIpcFops, LITEIPC_DRIVER_MODE, NULL);
1170d163575Sopenharmony_ci    if (ret != LOS_OK) {
1180d163575Sopenharmony_ci        PRINT_ERR("register lite_ipc driver failed:%d\n", ret);
1190d163575Sopenharmony_ci    }
1200d163575Sopenharmony_ci    LOS_ListInit(&(g_ipcPendlist));
1210d163575Sopenharmony_ci
1220d163575Sopenharmony_ci    return ret;
1230d163575Sopenharmony_ci}
1240d163575Sopenharmony_ci
1250d163575Sopenharmony_ciLOS_MODULE_INIT(OsLiteIpcInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
1260d163575Sopenharmony_ci
1270d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcOpen(struct file *filep)
1280d163575Sopenharmony_ci{
1290d163575Sopenharmony_ci    LosProcessCB *pcb = OsCurrProcessGet();
1300d163575Sopenharmony_ci    if (pcb->ipcInfo != NULL) {
1310d163575Sopenharmony_ci        return 0;
1320d163575Sopenharmony_ci    }
1330d163575Sopenharmony_ci
1340d163575Sopenharmony_ci    pcb->ipcInfo = LiteIpcPoolCreate();
1350d163575Sopenharmony_ci    if (pcb->ipcInfo == NULL) {
1360d163575Sopenharmony_ci        return -ENOMEM;
1370d163575Sopenharmony_ci    }
1380d163575Sopenharmony_ci
1390d163575Sopenharmony_ci    return 0;
1400d163575Sopenharmony_ci}
1410d163575Sopenharmony_ci
1420d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcClose(struct file *filep)
1430d163575Sopenharmony_ci{
1440d163575Sopenharmony_ci    return 0;
1450d163575Sopenharmony_ci}
1460d163575Sopenharmony_ci
1470d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsPoolMapped(ProcIpcInfo *ipcInfo)
1480d163575Sopenharmony_ci{
1490d163575Sopenharmony_ci    return (ipcInfo->pool.uvaddr != NULL) && (ipcInfo->pool.kvaddr != NULL) &&
1500d163575Sopenharmony_ci        (ipcInfo->pool.poolSize != 0);
1510d163575Sopenharmony_ci}
1520d163575Sopenharmony_ci
1530d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INT32 DoIpcMmap(LosProcessCB *pcb, LosVmMapRegion *region)
1540d163575Sopenharmony_ci{
1550d163575Sopenharmony_ci    UINT32 i;
1560d163575Sopenharmony_ci    INT32 ret = 0;
1570d163575Sopenharmony_ci    PADDR_T pa;
1580d163575Sopenharmony_ci    UINT32 uflags = VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_USER;
1590d163575Sopenharmony_ci    LosVmPage *vmPage = NULL;
1600d163575Sopenharmony_ci    VADDR_T uva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.uvaddr;
1610d163575Sopenharmony_ci    VADDR_T kva = (VADDR_T)(UINTPTR)pcb->ipcInfo->pool.kvaddr;
1620d163575Sopenharmony_ci
1630d163575Sopenharmony_ci    (VOID)LOS_MuxAcquire(&pcb->vmSpace->regionMux);
1640d163575Sopenharmony_ci
1650d163575Sopenharmony_ci    for (i = 0; i < (region->range.size >> PAGE_SHIFT); i++) {
1660d163575Sopenharmony_ci        pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT)));
1670d163575Sopenharmony_ci        if (pa == 0) {
1680d163575Sopenharmony_ci            PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
1690d163575Sopenharmony_ci            ret = -EINVAL;
1700d163575Sopenharmony_ci            break;
1710d163575Sopenharmony_ci        }
1720d163575Sopenharmony_ci        vmPage = LOS_VmPageGet(pa);
1730d163575Sopenharmony_ci        if (vmPage == NULL) {
1740d163575Sopenharmony_ci            PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
1750d163575Sopenharmony_ci            ret = -EINVAL;
1760d163575Sopenharmony_ci            break;
1770d163575Sopenharmony_ci        }
1780d163575Sopenharmony_ci        STATUS_T err = LOS_ArchMmuMap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), pa, 1, uflags);
1790d163575Sopenharmony_ci        if (err < 0) {
1800d163575Sopenharmony_ci            ret = err;
1810d163575Sopenharmony_ci            PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
1820d163575Sopenharmony_ci            break;
1830d163575Sopenharmony_ci        }
1840d163575Sopenharmony_ci    }
1850d163575Sopenharmony_ci    /* if any failure happened, rollback */
1860d163575Sopenharmony_ci    if (i != (region->range.size >> PAGE_SHIFT)) {
1870d163575Sopenharmony_ci        while (i--) {
1880d163575Sopenharmony_ci            pa = LOS_PaddrQuery((VOID *)(UINTPTR)(kva + (i << PAGE_SHIFT)));
1890d163575Sopenharmony_ci            vmPage = LOS_VmPageGet(pa);
1900d163575Sopenharmony_ci            (VOID)LOS_ArchMmuUnmap(&pcb->vmSpace->archMmu, uva + (i << PAGE_SHIFT), 1);
1910d163575Sopenharmony_ci            LOS_PhysPageFree(vmPage);
1920d163575Sopenharmony_ci        }
1930d163575Sopenharmony_ci    }
1940d163575Sopenharmony_ci
1950d163575Sopenharmony_ci    (VOID)LOS_MuxRelease(&pcb->vmSpace->regionMux);
1960d163575Sopenharmony_ci    return ret;
1970d163575Sopenharmony_ci}
1980d163575Sopenharmony_ci
1990d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC int LiteIpcMmap(struct file *filep, LosVmMapRegion *region)
2000d163575Sopenharmony_ci{
2010d163575Sopenharmony_ci    int ret = 0;
2020d163575Sopenharmony_ci    LosVmMapRegion *regionTemp = NULL;
2030d163575Sopenharmony_ci    LosProcessCB *pcb = OsCurrProcessGet();
2040d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = pcb->ipcInfo;
2050d163575Sopenharmony_ci
2060d163575Sopenharmony_ci    if ((ipcInfo == NULL) || (region == NULL) || (region->range.size > LITE_IPC_POOL_MAX_SIZE) ||
2070d163575Sopenharmony_ci        (!LOS_IsRegionPermUserReadOnly(region)) || (!LOS_IsRegionFlagPrivateOnly(region))) {
2080d163575Sopenharmony_ci        ret = -EINVAL;
2090d163575Sopenharmony_ci        goto ERROR_REGION_OUT;
2100d163575Sopenharmony_ci    }
2110d163575Sopenharmony_ci    if (IsPoolMapped(ipcInfo)) {
2120d163575Sopenharmony_ci        return -EEXIST;
2130d163575Sopenharmony_ci    }
2140d163575Sopenharmony_ci    if (ipcInfo->pool.uvaddr != NULL) {
2150d163575Sopenharmony_ci        regionTemp = LOS_RegionFind(pcb->vmSpace, (VADDR_T)(UINTPTR)ipcInfo->pool.uvaddr);
2160d163575Sopenharmony_ci        if (regionTemp != NULL) {
2170d163575Sopenharmony_ci            (VOID)LOS_RegionFree(pcb->vmSpace, regionTemp);
2180d163575Sopenharmony_ci        }
2190d163575Sopenharmony_ci    }
2200d163575Sopenharmony_ci    ipcInfo->pool.uvaddr = (VOID *)(UINTPTR)region->range.base;
2210d163575Sopenharmony_ci    if (ipcInfo->pool.kvaddr != NULL) {
2220d163575Sopenharmony_ci        LOS_VFree(ipcInfo->pool.kvaddr);
2230d163575Sopenharmony_ci        ipcInfo->pool.kvaddr = NULL;
2240d163575Sopenharmony_ci    }
2250d163575Sopenharmony_ci    /* use vmalloc to alloc phy mem */
2260d163575Sopenharmony_ci    ipcInfo->pool.kvaddr = LOS_VMalloc(region->range.size);
2270d163575Sopenharmony_ci    if (ipcInfo->pool.kvaddr == NULL) {
2280d163575Sopenharmony_ci        ret = -ENOMEM;
2290d163575Sopenharmony_ci        goto ERROR_REGION_OUT;
2300d163575Sopenharmony_ci    }
2310d163575Sopenharmony_ci    /* do mmap */
2320d163575Sopenharmony_ci    ret = DoIpcMmap(pcb, region);
2330d163575Sopenharmony_ci    if (ret) {
2340d163575Sopenharmony_ci        goto ERROR_MAP_OUT;
2350d163575Sopenharmony_ci    }
2360d163575Sopenharmony_ci    /* ipc pool init */
2370d163575Sopenharmony_ci    if (LOS_MemInit(ipcInfo->pool.kvaddr, region->range.size) != LOS_OK) {
2380d163575Sopenharmony_ci        ret = -EINVAL;
2390d163575Sopenharmony_ci        goto ERROR_MAP_OUT;
2400d163575Sopenharmony_ci    }
2410d163575Sopenharmony_ci    ipcInfo->pool.poolSize = region->range.size;
2420d163575Sopenharmony_ci    region->regionFlags |= VM_MAP_REGION_FLAG_LITEIPC;
2430d163575Sopenharmony_ci    return 0;
2440d163575Sopenharmony_ciERROR_MAP_OUT:
2450d163575Sopenharmony_ci    LOS_VFree(ipcInfo->pool.kvaddr);
2460d163575Sopenharmony_ciERROR_REGION_OUT:
2470d163575Sopenharmony_ci    if (ipcInfo != NULL) {
2480d163575Sopenharmony_ci        ipcInfo->pool.uvaddr = NULL;
2490d163575Sopenharmony_ci        ipcInfo->pool.kvaddr = NULL;
2500d163575Sopenharmony_ci    }
2510d163575Sopenharmony_ci    return ret;
2520d163575Sopenharmony_ci}
2530d163575Sopenharmony_ci
2540d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC UINT32 LiteIpcPoolInit(ProcIpcInfo *ipcInfo)
2550d163575Sopenharmony_ci{
2560d163575Sopenharmony_ci    ipcInfo->pool.uvaddr = NULL;
2570d163575Sopenharmony_ci    ipcInfo->pool.kvaddr = NULL;
2580d163575Sopenharmony_ci    ipcInfo->pool.poolSize = 0;
2590d163575Sopenharmony_ci    ipcInfo->ipcTaskID = INVAILD_ID;
2600d163575Sopenharmony_ci    LOS_ListInit(&ipcInfo->ipcUsedNodelist);
2610d163575Sopenharmony_ci    return LOS_OK;
2620d163575Sopenharmony_ci}
2630d163575Sopenharmony_ci
2640d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC ProcIpcInfo *LiteIpcPoolCreate(VOID)
2650d163575Sopenharmony_ci{
2660d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = LOS_MemAlloc(m_aucSysMem1, sizeof(ProcIpcInfo));
2670d163575Sopenharmony_ci    if (ipcInfo == NULL) {
2680d163575Sopenharmony_ci        return NULL;
2690d163575Sopenharmony_ci    }
2700d163575Sopenharmony_ci
2710d163575Sopenharmony_ci    (VOID)memset_s(ipcInfo, sizeof(ProcIpcInfo), 0, sizeof(ProcIpcInfo));
2720d163575Sopenharmony_ci
2730d163575Sopenharmony_ci    (VOID)LiteIpcPoolInit(ipcInfo);
2740d163575Sopenharmony_ci    return ipcInfo;
2750d163575Sopenharmony_ci}
2760d163575Sopenharmony_ci
2770d163575Sopenharmony_ciLITE_OS_SEC_TEXT ProcIpcInfo *LiteIpcPoolReInit(const ProcIpcInfo *parent)
2780d163575Sopenharmony_ci{
2790d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = LiteIpcPoolCreate();
2800d163575Sopenharmony_ci    if (ipcInfo == NULL) {
2810d163575Sopenharmony_ci        return NULL;
2820d163575Sopenharmony_ci    }
2830d163575Sopenharmony_ci
2840d163575Sopenharmony_ci    ipcInfo->pool.uvaddr = parent->pool.uvaddr;
2850d163575Sopenharmony_ci    ipcInfo->pool.kvaddr = NULL;
2860d163575Sopenharmony_ci    ipcInfo->pool.poolSize = 0;
2870d163575Sopenharmony_ci    ipcInfo->ipcTaskID = INVAILD_ID;
2880d163575Sopenharmony_ci    return ipcInfo;
2890d163575Sopenharmony_ci}
2900d163575Sopenharmony_ci
2910d163575Sopenharmony_ciSTATIC VOID LiteIpcPoolDelete(ProcIpcInfo *ipcInfo, UINT32 processID)
2920d163575Sopenharmony_ci{
2930d163575Sopenharmony_ci    UINT32 intSave;
2940d163575Sopenharmony_ci    IpcUsedNode *node = NULL;
2950d163575Sopenharmony_ci    if (ipcInfo->pool.kvaddr != NULL) {
2960d163575Sopenharmony_ci        LOS_VFree(ipcInfo->pool.kvaddr);
2970d163575Sopenharmony_ci        ipcInfo->pool.kvaddr = NULL;
2980d163575Sopenharmony_ci        IPC_LOCK(intSave);
2990d163575Sopenharmony_ci        while (!LOS_ListEmpty(&ipcInfo->ipcUsedNodelist)) {
3000d163575Sopenharmony_ci            node = LOS_DL_LIST_ENTRY(ipcInfo->ipcUsedNodelist.pstNext, IpcUsedNode, list);
3010d163575Sopenharmony_ci            LOS_ListDelete(&node->list);
3020d163575Sopenharmony_ci            free(node);
3030d163575Sopenharmony_ci        }
3040d163575Sopenharmony_ci        IPC_UNLOCK(intSave);
3050d163575Sopenharmony_ci    }
3060d163575Sopenharmony_ci    /* remove process access to service */
3070d163575Sopenharmony_ci    for (UINT32 i = 0; i < MAX_SERVICE_NUM; i++) {
3080d163575Sopenharmony_ci        if (ipcInfo->access[i] == TRUE) {
3090d163575Sopenharmony_ci            ipcInfo->access[i] = FALSE;
3100d163575Sopenharmony_ci            if (OS_TCB_FROM_TID(i)->ipcTaskInfo != NULL) {
3110d163575Sopenharmony_ci                OS_TCB_FROM_TID(i)->ipcTaskInfo->accessMap[processID] = FALSE;
3120d163575Sopenharmony_ci            }
3130d163575Sopenharmony_ci        }
3140d163575Sopenharmony_ci    }
3150d163575Sopenharmony_ci}
3160d163575Sopenharmony_ci
3170d163575Sopenharmony_ciLITE_OS_SEC_TEXT UINT32 LiteIpcPoolDestroy(UINT32 processID)
3180d163575Sopenharmony_ci{
3190d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_PID(processID);
3200d163575Sopenharmony_ci    if (pcb->ipcInfo == NULL) {
3210d163575Sopenharmony_ci        return LOS_NOK;
3220d163575Sopenharmony_ci    }
3230d163575Sopenharmony_ci
3240d163575Sopenharmony_ci    LiteIpcPoolDelete(pcb->ipcInfo, pcb->processID);
3250d163575Sopenharmony_ci    LOS_MemFree(m_aucSysMem1, pcb->ipcInfo);
3260d163575Sopenharmony_ci    pcb->ipcInfo = NULL;
3270d163575Sopenharmony_ci    return LOS_OK;
3280d163575Sopenharmony_ci}
3290d163575Sopenharmony_ci
3300d163575Sopenharmony_ciLITE_OS_SEC_TEXT_INIT STATIC IpcTaskInfo *LiteIpcTaskInit(VOID)
3310d163575Sopenharmony_ci{
3320d163575Sopenharmony_ci    IpcTaskInfo *taskInfo = LOS_MemAlloc((VOID *)m_aucSysMem1, sizeof(IpcTaskInfo));
3330d163575Sopenharmony_ci    if (taskInfo == NULL) {
3340d163575Sopenharmony_ci        return NULL;
3350d163575Sopenharmony_ci    }
3360d163575Sopenharmony_ci
3370d163575Sopenharmony_ci    (VOID)memset_s(taskInfo, sizeof(IpcTaskInfo), 0, sizeof(IpcTaskInfo));
3380d163575Sopenharmony_ci    LOS_ListInit(&taskInfo->msgListHead);
3390d163575Sopenharmony_ci    return taskInfo;
3400d163575Sopenharmony_ci}
3410d163575Sopenharmony_ci
3420d163575Sopenharmony_ci/* Only when kernenl no longer access ipc node content, can user free the ipc node */
3430d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID EnableIpcNodeFreeByUser(LosProcessCB *pcb, VOID *buf)
3440d163575Sopenharmony_ci{
3450d163575Sopenharmony_ci    UINT32 intSave;
3460d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = pcb->ipcInfo;
3470d163575Sopenharmony_ci    IpcUsedNode *node = (IpcUsedNode *)malloc(sizeof(IpcUsedNode));
3480d163575Sopenharmony_ci    if (node != NULL) {
3490d163575Sopenharmony_ci        node->ptr = buf;
3500d163575Sopenharmony_ci        IPC_LOCK(intSave);
3510d163575Sopenharmony_ci        LOS_ListAdd(&ipcInfo->ipcUsedNodelist, &node->list);
3520d163575Sopenharmony_ci        IPC_UNLOCK(intSave);
3530d163575Sopenharmony_ci    }
3540d163575Sopenharmony_ci}
3550d163575Sopenharmony_ci
3560d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID *LiteIpcNodeAlloc(LosProcessCB *pcb, UINT32 size)
3570d163575Sopenharmony_ci{
3580d163575Sopenharmony_ci    VOID *ptr = LOS_MemAlloc(pcb->ipcInfo->pool.kvaddr, size);
3590d163575Sopenharmony_ci    PRINT_INFO("LiteIpcNodeAlloc pid:%d, pool:%x buf:%x size:%d\n",
3600d163575Sopenharmony_ci               pcb->processID, pcb->ipcInfo->pool.kvaddr, ptr, size);
3610d163575Sopenharmony_ci    return ptr;
3620d163575Sopenharmony_ci}
3630d163575Sopenharmony_ci
3640d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcNodeFree(LosProcessCB *pcb, VOID *buf)
3650d163575Sopenharmony_ci{
3660d163575Sopenharmony_ci    PRINT_INFO("LiteIpcNodeFree pid:%d, pool:%x buf:%x\n",
3670d163575Sopenharmony_ci               pcb->processID, pcb->ipcInfo->pool.kvaddr, buf);
3680d163575Sopenharmony_ci    return LOS_MemFree(pcb->ipcInfo->pool.kvaddr, buf);
3690d163575Sopenharmony_ci}
3700d163575Sopenharmony_ci
3710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsIpcNode(LosProcessCB *pcb, const VOID *buf)
3720d163575Sopenharmony_ci{
3730d163575Sopenharmony_ci    IpcUsedNode *node = NULL;
3740d163575Sopenharmony_ci    UINT32 intSave;
3750d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = pcb->ipcInfo;
3760d163575Sopenharmony_ci    IPC_LOCK(intSave);
3770d163575Sopenharmony_ci    LOS_DL_LIST_FOR_EACH_ENTRY(node, &ipcInfo->ipcUsedNodelist, IpcUsedNode, list) {
3780d163575Sopenharmony_ci        if (node->ptr == buf) {
3790d163575Sopenharmony_ci            LOS_ListDelete(&node->list);
3800d163575Sopenharmony_ci            IPC_UNLOCK(intSave);
3810d163575Sopenharmony_ci            free(node);
3820d163575Sopenharmony_ci            return TRUE;
3830d163575Sopenharmony_ci        }
3840d163575Sopenharmony_ci    }
3850d163575Sopenharmony_ci    IPC_UNLOCK(intSave);
3860d163575Sopenharmony_ci    return FALSE;
3870d163575Sopenharmony_ci}
3880d163575Sopenharmony_ci
3890d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INTPTR GetIpcUserAddr(const LosProcessCB *pcb, INTPTR kernelAddr)
3900d163575Sopenharmony_ci{
3910d163575Sopenharmony_ci    IpcPool pool = pcb->ipcInfo->pool;
3920d163575Sopenharmony_ci    INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr);
3930d163575Sopenharmony_ci    return kernelAddr + offset;
3940d163575Sopenharmony_ci}
3950d163575Sopenharmony_ci
3960d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC INTPTR GetIpcKernelAddr(const LosProcessCB *pcb, INTPTR userAddr)
3970d163575Sopenharmony_ci{
3980d163575Sopenharmony_ci    IpcPool pool = pcb->ipcInfo->pool;
3990d163575Sopenharmony_ci    INTPTR offset = (INTPTR)(pool.uvaddr) - (INTPTR)(pool.kvaddr);
4000d163575Sopenharmony_ci    return userAddr - offset;
4010d163575Sopenharmony_ci}
4020d163575Sopenharmony_ci
4030d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckUsedBuffer(const VOID *node, IpcListNode **outPtr)
4040d163575Sopenharmony_ci{
4050d163575Sopenharmony_ci    VOID *ptr = NULL;
4060d163575Sopenharmony_ci    LosProcessCB *pcb = OsCurrProcessGet();
4070d163575Sopenharmony_ci    IpcPool pool = pcb->ipcInfo->pool;
4080d163575Sopenharmony_ci    if ((node == NULL) || ((INTPTR)node < (INTPTR)(pool.uvaddr)) ||
4090d163575Sopenharmony_ci        ((INTPTR)node > (INTPTR)(pool.uvaddr) + pool.poolSize)) {
4100d163575Sopenharmony_ci        return -EINVAL;
4110d163575Sopenharmony_ci    }
4120d163575Sopenharmony_ci    ptr = (VOID *)GetIpcKernelAddr(pcb, (INTPTR)(node));
4130d163575Sopenharmony_ci    if (IsIpcNode(pcb, ptr) != TRUE) {
4140d163575Sopenharmony_ci        return -EFAULT;
4150d163575Sopenharmony_ci    }
4160d163575Sopenharmony_ci    *outPtr = (IpcListNode *)ptr;
4170d163575Sopenharmony_ci    return LOS_OK;
4180d163575Sopenharmony_ci}
4190d163575Sopenharmony_ci
4200d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GetTid(UINT32 serviceHandle, UINT32 *taskID)
4210d163575Sopenharmony_ci{
4220d163575Sopenharmony_ci    if (serviceHandle >= MAX_SERVICE_NUM) {
4230d163575Sopenharmony_ci        return -EINVAL;
4240d163575Sopenharmony_ci    }
4250d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
4260d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
4270d163575Sopenharmony_ci    *taskID = serviceHandle ? serviceHandle : g_cmsTask.taskID;
4280d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4290d163575Sopenharmony_ci    return LOS_OK;
4300d163575Sopenharmony_ci#else
4310d163575Sopenharmony_ci    if (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTED) {
4320d163575Sopenharmony_ci        *taskID = g_serviceHandleMap[serviceHandle].taskID;
4330d163575Sopenharmony_ci        (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4340d163575Sopenharmony_ci        return LOS_OK;
4350d163575Sopenharmony_ci    }
4360d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4370d163575Sopenharmony_ci    return -EINVAL;
4380d163575Sopenharmony_ci#endif
4390d163575Sopenharmony_ci}
4400d163575Sopenharmony_ci
4410d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GenerateServiceHandle(UINT32 taskID, HandleStatus status, UINT32 *serviceHandle)
4420d163575Sopenharmony_ci{
4430d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
4440d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
4450d163575Sopenharmony_ci    *serviceHandle = taskID ? taskID : LOS_CurTaskIDGet(); /* if taskID is 0, return curTaskID */
4460d163575Sopenharmony_ci    if (*serviceHandle != g_cmsTask.taskID) {
4470d163575Sopenharmony_ci        (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4480d163575Sopenharmony_ci        return LOS_OK;
4490d163575Sopenharmony_ci    }
4500d163575Sopenharmony_ci#else
4510d163575Sopenharmony_ci    for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) {
4520d163575Sopenharmony_ci        if (g_serviceHandleMap[i].status == HANDLE_NOT_USED) {
4530d163575Sopenharmony_ci            g_serviceHandleMap[i].taskID = taskID;
4540d163575Sopenharmony_ci            g_serviceHandleMap[i].status = status;
4550d163575Sopenharmony_ci            *serviceHandle = i;
4560d163575Sopenharmony_ci            (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4570d163575Sopenharmony_ci            return LOS_OK;
4580d163575Sopenharmony_ci        }
4590d163575Sopenharmony_ci    }
4600d163575Sopenharmony_ci#endif
4610d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4620d163575Sopenharmony_ci    return -EINVAL;
4630d163575Sopenharmony_ci}
4640d163575Sopenharmony_ci
4650d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC VOID RefreshServiceHandle(UINT32 serviceHandle, UINT32 result)
4660d163575Sopenharmony_ci{
4670d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 0)
4680d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
4690d163575Sopenharmony_ci    if ((result == LOS_OK) && (g_serviceHandleMap[serviceHandle].status == HANDLE_REGISTING)) {
4700d163575Sopenharmony_ci        g_serviceHandleMap[serviceHandle].status = HANDLE_REGISTED;
4710d163575Sopenharmony_ci    } else {
4720d163575Sopenharmony_ci        g_serviceHandleMap[serviceHandle].status = HANDLE_NOT_USED;
4730d163575Sopenharmony_ci    }
4740d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
4750d163575Sopenharmony_ci#endif
4760d163575Sopenharmony_ci}
4770d163575Sopenharmony_ci
4780d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 AddServiceAccess(UINT32 taskID, UINT32 serviceHandle)
4790d163575Sopenharmony_ci{
4800d163575Sopenharmony_ci    UINT32 serviceTid = 0;
4810d163575Sopenharmony_ci    UINT32 ret = GetTid(serviceHandle, &serviceTid);
4820d163575Sopenharmony_ci    if (ret != LOS_OK) {
4830d163575Sopenharmony_ci        PRINT_ERR("Liteipc AddServiceAccess GetTid failed\n");
4840d163575Sopenharmony_ci        return ret;
4850d163575Sopenharmony_ci    }
4860d163575Sopenharmony_ci
4870d163575Sopenharmony_ci    LosTaskCB *tcb = OS_TCB_FROM_TID(serviceTid);
4880d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_TID(taskID);
4890d163575Sopenharmony_ci    if ((tcb->ipcTaskInfo == NULL) || (pcb->ipcInfo == NULL)) {
4900d163575Sopenharmony_ci        PRINT_ERR("Liteipc AddServiceAccess ipc not create! pid %u tid %u\n", pcb->processID, tcb->taskID);
4910d163575Sopenharmony_ci        return -EINVAL;
4920d163575Sopenharmony_ci    }
4930d163575Sopenharmony_ci    tcb->ipcTaskInfo->accessMap[pcb->processID] = TRUE;
4940d163575Sopenharmony_ci    pcb->ipcInfo->access[serviceTid] = TRUE;
4950d163575Sopenharmony_ci    return LOS_OK;
4960d163575Sopenharmony_ci}
4970d163575Sopenharmony_ci
4980d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL HasServiceAccess(UINT32 serviceHandle)
4990d163575Sopenharmony_ci{
5000d163575Sopenharmony_ci    UINT32 serviceTid = 0;
5010d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
5020d163575Sopenharmony_ci    UINT32 ret;
5030d163575Sopenharmony_ci    if (serviceHandle >= MAX_SERVICE_NUM) {
5040d163575Sopenharmony_ci        return FALSE;
5050d163575Sopenharmony_ci    }
5060d163575Sopenharmony_ci    if (serviceHandle == 0) {
5070d163575Sopenharmony_ci        return TRUE;
5080d163575Sopenharmony_ci    }
5090d163575Sopenharmony_ci    ret = GetTid(serviceHandle, &serviceTid);
5100d163575Sopenharmony_ci    if (ret != LOS_OK) {
5110d163575Sopenharmony_ci        PRINT_ERR("Liteipc HasServiceAccess GetTid failed\n");
5120d163575Sopenharmony_ci        return FALSE;
5130d163575Sopenharmony_ci    }
5140d163575Sopenharmony_ci    LosTaskCB *taskCB = OS_TCB_FROM_TID(serviceTid);
5150d163575Sopenharmony_ci    if (taskCB->processCB == (UINTPTR)curr) {
5160d163575Sopenharmony_ci        return TRUE;
5170d163575Sopenharmony_ci    }
5180d163575Sopenharmony_ci
5190d163575Sopenharmony_ci    if (taskCB->ipcTaskInfo == NULL) {
5200d163575Sopenharmony_ci        return FALSE;
5210d163575Sopenharmony_ci    }
5220d163575Sopenharmony_ci
5230d163575Sopenharmony_ci    return taskCB->ipcTaskInfo->accessMap[curr->processID];
5240d163575Sopenharmony_ci}
5250d163575Sopenharmony_ci
5260d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SetIpcTask(VOID)
5270d163575Sopenharmony_ci{
5280d163575Sopenharmony_ci    if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) {
5290d163575Sopenharmony_ci        OsCurrProcessGet()->ipcInfo->ipcTaskID = LOS_CurTaskIDGet();
5300d163575Sopenharmony_ci        return OsCurrProcessGet()->ipcInfo->ipcTaskID;
5310d163575Sopenharmony_ci    }
5320d163575Sopenharmony_ci    PRINT_ERR("Liteipc curprocess %d IpcTask already set!\n", OsCurrProcessGet()->processID);
5330d163575Sopenharmony_ci    return -EINVAL;
5340d163575Sopenharmony_ci}
5350d163575Sopenharmony_ci
5360d163575Sopenharmony_ciLITE_OS_SEC_TEXT BOOL IsIpcTaskSet(VOID)
5370d163575Sopenharmony_ci{
5380d163575Sopenharmony_ci    if (OsCurrProcessGet()->ipcInfo->ipcTaskID == INVAILD_ID) {
5390d163575Sopenharmony_ci        return FALSE;
5400d163575Sopenharmony_ci    }
5410d163575Sopenharmony_ci    return TRUE;
5420d163575Sopenharmony_ci}
5430d163575Sopenharmony_ci
5440d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 GetIpcTaskID(LosProcessCB *pcb, UINT32 *ipcTaskID)
5450d163575Sopenharmony_ci{
5460d163575Sopenharmony_ci    if (pcb->ipcInfo->ipcTaskID == INVAILD_ID) {
5470d163575Sopenharmony_ci        return LOS_NOK;
5480d163575Sopenharmony_ci    }
5490d163575Sopenharmony_ci    *ipcTaskID = pcb->ipcInfo->ipcTaskID;
5500d163575Sopenharmony_ci    return LOS_OK;
5510d163575Sopenharmony_ci}
5520d163575Sopenharmony_ci
5530d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SendDeathMsg(UINT32 processID, UINT32 serviceHandle)
5540d163575Sopenharmony_ci{
5550d163575Sopenharmony_ci    UINT32 ipcTaskID;
5560d163575Sopenharmony_ci    UINT32 ret;
5570d163575Sopenharmony_ci    IpcContent content;
5580d163575Sopenharmony_ci    IpcMsg msg;
5590d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_PID(processID);
5600d163575Sopenharmony_ci
5610d163575Sopenharmony_ci    if (pcb->ipcInfo == NULL) {
5620d163575Sopenharmony_ci        return -EINVAL;
5630d163575Sopenharmony_ci    }
5640d163575Sopenharmony_ci
5650d163575Sopenharmony_ci    pcb->ipcInfo->access[serviceHandle] = FALSE;
5660d163575Sopenharmony_ci
5670d163575Sopenharmony_ci    ret = GetIpcTaskID(pcb, &ipcTaskID);
5680d163575Sopenharmony_ci    if (ret != LOS_OK) {
5690d163575Sopenharmony_ci        return -EINVAL;
5700d163575Sopenharmony_ci    }
5710d163575Sopenharmony_ci    content.flag = SEND;
5720d163575Sopenharmony_ci    content.outMsg = &msg;
5730d163575Sopenharmony_ci    (void)memset_s(content.outMsg, sizeof(IpcMsg), 0, sizeof(IpcMsg));
5740d163575Sopenharmony_ci    content.outMsg->type = MT_DEATH_NOTIFY;
5750d163575Sopenharmony_ci    content.outMsg->target.handle = ipcTaskID;
5760d163575Sopenharmony_ci    content.outMsg->target.token = serviceHandle;
5770d163575Sopenharmony_ci    content.outMsg->code = 0;
5780d163575Sopenharmony_ci    return LiteIpcWrite(&content);
5790d163575Sopenharmony_ci}
5800d163575Sopenharmony_ci
5810d163575Sopenharmony_ciLITE_OS_SEC_TEXT VOID LiteIpcRemoveServiceHandle(UINT32 taskID)
5820d163575Sopenharmony_ci{
5830d163575Sopenharmony_ci    UINT32 j;
5840d163575Sopenharmony_ci    LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
5850d163575Sopenharmony_ci    IpcTaskInfo *ipcTaskInfo = taskCB->ipcTaskInfo;
5860d163575Sopenharmony_ci    if (ipcTaskInfo == NULL) {
5870d163575Sopenharmony_ci        return;
5880d163575Sopenharmony_ci    }
5890d163575Sopenharmony_ci
5900d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
5910d163575Sopenharmony_ci
5920d163575Sopenharmony_ci    UINT32 intSave;
5930d163575Sopenharmony_ci    LOS_DL_LIST *listHead = NULL;
5940d163575Sopenharmony_ci    LOS_DL_LIST *listNode = NULL;
5950d163575Sopenharmony_ci    IpcListNode *node = NULL;
5960d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_TCB(taskCB);
5970d163575Sopenharmony_ci
5980d163575Sopenharmony_ci    listHead = &(ipcTaskInfo->msgListHead);
5990d163575Sopenharmony_ci    do {
6000d163575Sopenharmony_ci        SCHEDULER_LOCK(intSave);
6010d163575Sopenharmony_ci        if (LOS_ListEmpty(listHead)) {
6020d163575Sopenharmony_ci            SCHEDULER_UNLOCK(intSave);
6030d163575Sopenharmony_ci            break;
6040d163575Sopenharmony_ci        } else {
6050d163575Sopenharmony_ci            listNode = LOS_DL_LIST_FIRST(listHead);
6060d163575Sopenharmony_ci            LOS_ListDelete(listNode);
6070d163575Sopenharmony_ci            node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode);
6080d163575Sopenharmony_ci            SCHEDULER_UNLOCK(intSave);
6090d163575Sopenharmony_ci            (VOID)HandleSpecialObjects(taskCB->taskID, node, TRUE);
6100d163575Sopenharmony_ci            (VOID)LiteIpcNodeFree(pcb, (VOID *)node);
6110d163575Sopenharmony_ci        }
6120d163575Sopenharmony_ci    } while (1);
6130d163575Sopenharmony_ci
6140d163575Sopenharmony_ci    ipcTaskInfo->accessMap[pcb->processID] = FALSE;
6150d163575Sopenharmony_ci    for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) {
6160d163575Sopenharmony_ci        if (ipcTaskInfo->accessMap[j] == TRUE) {
6170d163575Sopenharmony_ci            ipcTaskInfo->accessMap[j] = FALSE;
6180d163575Sopenharmony_ci            (VOID)SendDeathMsg(j, taskCB->taskID);
6190d163575Sopenharmony_ci        }
6200d163575Sopenharmony_ci    }
6210d163575Sopenharmony_ci#else
6220d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
6230d163575Sopenharmony_ci    for (UINT32 i = 1; i < MAX_SERVICE_NUM; i++) {
6240d163575Sopenharmony_ci        if ((g_serviceHandleMap[i].status != HANDLE_NOT_USED) && (g_serviceHandleMap[i].taskID == taskCB->taskID)) {
6250d163575Sopenharmony_ci            g_serviceHandleMap[i].status = HANDLE_NOT_USED;
6260d163575Sopenharmony_ci            g_serviceHandleMap[i].taskID = INVAILD_ID;
6270d163575Sopenharmony_ci            break;
6280d163575Sopenharmony_ci        }
6290d163575Sopenharmony_ci    }
6300d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6310d163575Sopenharmony_ci    /* run deathHandler */
6320d163575Sopenharmony_ci    if (i < MAX_SERVICE_NUM) {
6330d163575Sopenharmony_ci        for (j = 0; j < LOSCFG_BASE_CORE_PROCESS_LIMIT; j++) {
6340d163575Sopenharmony_ci            if (ipcTaskInfo->accessMap[j] == TRUE) {
6350d163575Sopenharmony_ci                (VOID)SendDeathMsg(j, i);
6360d163575Sopenharmony_ci            }
6370d163575Sopenharmony_ci        }
6380d163575Sopenharmony_ci    }
6390d163575Sopenharmony_ci#endif
6400d163575Sopenharmony_ci
6410d163575Sopenharmony_ci    (VOID)LOS_MemFree(m_aucSysMem1, ipcTaskInfo);
6420d163575Sopenharmony_ci    taskCB->ipcTaskInfo = NULL;
6430d163575Sopenharmony_ci}
6440d163575Sopenharmony_ci
6450d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 SetCms(UINTPTR maxMsgSize)
6460d163575Sopenharmony_ci{
6470d163575Sopenharmony_ci    if (maxMsgSize < sizeof(IpcMsg)) {
6480d163575Sopenharmony_ci        return -EINVAL;
6490d163575Sopenharmony_ci    }
6500d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
6510d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
6520d163575Sopenharmony_ci    if (g_cmsTask.status == HANDLE_NOT_USED) {
6530d163575Sopenharmony_ci        g_cmsTask.status = HANDLE_REGISTED;
6540d163575Sopenharmony_ci        g_cmsTask.taskID = LOS_CurTaskIDGet();
6550d163575Sopenharmony_ci        g_cmsTask.maxMsgSize = maxMsgSize;
6560d163575Sopenharmony_ci        (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6570d163575Sopenharmony_ci        return LOS_OK;
6580d163575Sopenharmony_ci    }
6590d163575Sopenharmony_ci#else
6600d163575Sopenharmony_ci    if (g_serviceHandleMap[0].status == HANDLE_NOT_USED) {
6610d163575Sopenharmony_ci        g_serviceHandleMap[0].status = HANDLE_REGISTED;
6620d163575Sopenharmony_ci        g_serviceHandleMap[0].taskID = LOS_CurTaskIDGet();
6630d163575Sopenharmony_ci        (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6640d163575Sopenharmony_ci        return LOS_OK;
6650d163575Sopenharmony_ci    }
6660d163575Sopenharmony_ci#endif
6670d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6680d163575Sopenharmony_ci    return -EEXIST;
6690d163575Sopenharmony_ci}
6700d163575Sopenharmony_ci
6710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsCmsSet(VOID)
6720d163575Sopenharmony_ci{
6730d163575Sopenharmony_ci    BOOL ret;
6740d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
6750d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
6760d163575Sopenharmony_ci    ret = g_cmsTask.status == HANDLE_REGISTED;
6770d163575Sopenharmony_ci#else
6780d163575Sopenharmony_ci    ret = g_serviceHandleMap[0].status == HANDLE_REGISTED;
6790d163575Sopenharmony_ci#endif
6800d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6810d163575Sopenharmony_ci    return ret;
6820d163575Sopenharmony_ci}
6830d163575Sopenharmony_ci
6840d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsCmsTask(UINT32 taskID)
6850d163575Sopenharmony_ci{
6860d163575Sopenharmony_ci    BOOL ret;
6870d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
6880d163575Sopenharmony_ci#if (USE_TASKID_AS_HANDLE == 1)
6890d163575Sopenharmony_ci    ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB == OS_TCB_FROM_TID(g_cmsTask.taskID)->processCB) : FALSE;
6900d163575Sopenharmony_ci#else
6910d163575Sopenharmony_ci    ret = IsCmsSet() ? (OS_TCB_FROM_TID(taskID)->processCB ==
6920d163575Sopenharmony_ci        OS_TCB_FROM_TID(g_serviceHandleMap[0].taskID)->processCB) : FALSE;
6930d163575Sopenharmony_ci#endif
6940d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
6950d163575Sopenharmony_ci    return ret;
6960d163575Sopenharmony_ci}
6970d163575Sopenharmony_ci
6980d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID)
6990d163575Sopenharmony_ci{
7000d163575Sopenharmony_ci    LosTaskCB *tcb = NULL;
7010d163575Sopenharmony_ci    if (OS_TID_CHECK_INVALID(taskID)) {
7020d163575Sopenharmony_ci        return FALSE;
7030d163575Sopenharmony_ci    }
7040d163575Sopenharmony_ci    tcb = OS_TCB_FROM_TID(taskID);
7050d163575Sopenharmony_ci    if (OsTaskIsUnused(tcb)) {
7060d163575Sopenharmony_ci        return FALSE;
7070d163575Sopenharmony_ci    }
7080d163575Sopenharmony_ci    if (OsTaskIsInactive(tcb)) {
7090d163575Sopenharmony_ci        return FALSE;
7100d163575Sopenharmony_ci    }
7110d163575Sopenharmony_ci    if (!OsTaskIsUserMode(tcb)) {
7120d163575Sopenharmony_ci        return FALSE;
7130d163575Sopenharmony_ci    }
7140d163575Sopenharmony_ci    return TRUE;
7150d163575Sopenharmony_ci}
7160d163575Sopenharmony_ci
7170d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleFd(const LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback)
7180d163575Sopenharmony_ci{
7190d163575Sopenharmony_ci    int ret;
7200d163575Sopenharmony_ci    if (isRollback == FALSE) {
7210d163575Sopenharmony_ci        ret = CopyFdToProc(obj->content.fd, pcb->processID);
7220d163575Sopenharmony_ci        if (ret < 0) {
7230d163575Sopenharmony_ci            return ret;
7240d163575Sopenharmony_ci        }
7250d163575Sopenharmony_ci        obj->content.fd = ret;
7260d163575Sopenharmony_ci    } else {
7270d163575Sopenharmony_ci        ret = CloseProcFd(obj->content.fd, pcb->processID);
7280d163575Sopenharmony_ci        if (ret < 0) {
7290d163575Sopenharmony_ci            return ret;
7300d163575Sopenharmony_ci        }
7310d163575Sopenharmony_ci    }
7320d163575Sopenharmony_ci
7330d163575Sopenharmony_ci    return LOS_OK;
7340d163575Sopenharmony_ci}
7350d163575Sopenharmony_ci
7360d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(LosProcessCB *pcb, SpecialObj *obj, BOOL isRollback)
7370d163575Sopenharmony_ci{
7380d163575Sopenharmony_ci    VOID *buf = NULL;
7390d163575Sopenharmony_ci    UINT32 ret;
7400d163575Sopenharmony_ci    if ((obj->content.ptr.buff == NULL) || (obj->content.ptr.buffSz == 0)) {
7410d163575Sopenharmony_ci        return -EINVAL;
7420d163575Sopenharmony_ci    }
7430d163575Sopenharmony_ci    if (isRollback == FALSE) {
7440d163575Sopenharmony_ci        if (LOS_IsUserAddress((vaddr_t)(UINTPTR)(obj->content.ptr.buff)) == FALSE) {
7450d163575Sopenharmony_ci            PRINT_ERR("Liteipc Bad ptr address\n");
7460d163575Sopenharmony_ci            return -EINVAL;
7470d163575Sopenharmony_ci        }
7480d163575Sopenharmony_ci        buf = LiteIpcNodeAlloc(pcb, obj->content.ptr.buffSz);
7490d163575Sopenharmony_ci        if (buf == NULL) {
7500d163575Sopenharmony_ci            PRINT_ERR("Liteipc DealPtr alloc mem failed\n");
7510d163575Sopenharmony_ci            return -EINVAL;
7520d163575Sopenharmony_ci        }
7530d163575Sopenharmony_ci        ret = copy_from_user(buf, obj->content.ptr.buff, obj->content.ptr.buffSz);
7540d163575Sopenharmony_ci        if (ret != LOS_OK) {
7550d163575Sopenharmony_ci            LiteIpcNodeFree(pcb, buf);
7560d163575Sopenharmony_ci            return ret;
7570d163575Sopenharmony_ci        }
7580d163575Sopenharmony_ci        obj->content.ptr.buff = (VOID *)GetIpcUserAddr(pcb, (INTPTR)buf);
7590d163575Sopenharmony_ci        EnableIpcNodeFreeByUser(pcb, (VOID *)buf);
7600d163575Sopenharmony_ci    } else {
7610d163575Sopenharmony_ci        buf = (VOID *)GetIpcKernelAddr(pcb, (INTPTR)obj->content.ptr.buff);
7620d163575Sopenharmony_ci        if (IsIpcNode(pcb, buf) == TRUE) {
7630d163575Sopenharmony_ci            (VOID)LiteIpcNodeFree(pcb, buf);
7640d163575Sopenharmony_ci        }
7650d163575Sopenharmony_ci    }
7660d163575Sopenharmony_ci    return LOS_OK;
7670d163575Sopenharmony_ci}
7680d163575Sopenharmony_ci
7690d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleSvc(UINT32 dstTid, SpecialObj *obj, BOOL isRollback)
7700d163575Sopenharmony_ci{
7710d163575Sopenharmony_ci    UINT32 taskID = 0;
7720d163575Sopenharmony_ci    if (isRollback == FALSE) {
7730d163575Sopenharmony_ci        if (obj->content.svc.handle == -1) {
7740d163575Sopenharmony_ci            if (obj->content.svc.token != 1) {
7750d163575Sopenharmony_ci                PRINT_ERR("Liteipc HandleSvc wrong svc token\n");
7760d163575Sopenharmony_ci                return -EINVAL;
7770d163575Sopenharmony_ci            }
7780d163575Sopenharmony_ci            UINT32 selfTid = LOS_CurTaskIDGet();
7790d163575Sopenharmony_ci            LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid);
7800d163575Sopenharmony_ci            if (tcb->ipcTaskInfo == NULL) {
7810d163575Sopenharmony_ci                tcb->ipcTaskInfo = LiteIpcTaskInit();
7820d163575Sopenharmony_ci            }
7830d163575Sopenharmony_ci            uint32_t serviceHandle = 0;
7840d163575Sopenharmony_ci            UINT32 ret = GenerateServiceHandle(selfTid, HANDLE_REGISTED, &serviceHandle);
7850d163575Sopenharmony_ci            if (ret != LOS_OK) {
7860d163575Sopenharmony_ci                PRINT_ERR("Liteipc GenerateServiceHandle failed.\n");
7870d163575Sopenharmony_ci                return ret;
7880d163575Sopenharmony_ci            }
7890d163575Sopenharmony_ci            obj->content.svc.handle = serviceHandle;
7900d163575Sopenharmony_ci            (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
7910d163575Sopenharmony_ci            AddServiceAccess(dstTid, serviceHandle);
7920d163575Sopenharmony_ci            (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
7930d163575Sopenharmony_ci        }
7940d163575Sopenharmony_ci        if (IsTaskAlive(obj->content.svc.handle) == FALSE) {
7950d163575Sopenharmony_ci            PRINT_ERR("Liteipc HandleSvc wrong svctid\n");
7960d163575Sopenharmony_ci            return -EINVAL;
7970d163575Sopenharmony_ci        }
7980d163575Sopenharmony_ci        if (HasServiceAccess(obj->content.svc.handle) == FALSE) {
7990d163575Sopenharmony_ci            PRINT_ERR("Liteipc %s, %d, svchandle:%d, tid:%d\n", __FUNCTION__, __LINE__, obj->content.svc.handle, LOS_CurTaskIDGet());
8000d163575Sopenharmony_ci            return -EACCES;
8010d163575Sopenharmony_ci        }
8020d163575Sopenharmony_ci        LosTaskCB *taskCb = OS_TCB_FROM_TID(obj->content.svc.handle);
8030d163575Sopenharmony_ci        if (taskCb->ipcTaskInfo == NULL) {
8040d163575Sopenharmony_ci            taskCb->ipcTaskInfo = LiteIpcTaskInit();
8050d163575Sopenharmony_ci        }
8060d163575Sopenharmony_ci        if (GetTid(obj->content.svc.handle, &taskID) == 0) {
8070d163575Sopenharmony_ci            AddServiceAccess(dstTid, obj->content.svc.handle);
8080d163575Sopenharmony_ci        }
8090d163575Sopenharmony_ci    }
8100d163575Sopenharmony_ci    return LOS_OK;
8110d163575Sopenharmony_ci}
8120d163575Sopenharmony_ci
8130d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL isRollback)
8140d163575Sopenharmony_ci{
8150d163575Sopenharmony_ci    UINT32 ret;
8160d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_TID(dstTid);
8170d163575Sopenharmony_ci    switch (obj->type) {
8180d163575Sopenharmony_ci        case OBJ_FD:
8190d163575Sopenharmony_ci            ret = HandleFd(pcb, obj, isRollback);
8200d163575Sopenharmony_ci            break;
8210d163575Sopenharmony_ci        case OBJ_PTR:
8220d163575Sopenharmony_ci            ret = HandlePtr(pcb, obj, isRollback);
8230d163575Sopenharmony_ci            break;
8240d163575Sopenharmony_ci        case OBJ_SVC:
8250d163575Sopenharmony_ci            ret = HandleSvc(dstTid, (SpecialObj *)obj, isRollback);
8260d163575Sopenharmony_ci            break;
8270d163575Sopenharmony_ci        default:
8280d163575Sopenharmony_ci            ret = -EINVAL;
8290d163575Sopenharmony_ci            break;
8300d163575Sopenharmony_ci    }
8310d163575Sopenharmony_ci    return ret;
8320d163575Sopenharmony_ci}
8330d163575Sopenharmony_ci
8340d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleSpecialObjects(UINT32 dstTid, IpcListNode *node, BOOL isRollback)
8350d163575Sopenharmony_ci{
8360d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
8370d163575Sopenharmony_ci    IpcMsg *msg = &(node->msg);
8380d163575Sopenharmony_ci    INT32 i;
8390d163575Sopenharmony_ci    SpecialObj *obj = NULL;
8400d163575Sopenharmony_ci    UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets);
8410d163575Sopenharmony_ci    if (isRollback) {
8420d163575Sopenharmony_ci        i = msg->spObjNum;
8430d163575Sopenharmony_ci        goto EXIT;
8440d163575Sopenharmony_ci    }
8450d163575Sopenharmony_ci    for (i = 0; i < msg->spObjNum; i++) {
8460d163575Sopenharmony_ci        if (offset[i] > msg->dataSz - sizeof(SpecialObj)) {
8470d163575Sopenharmony_ci            ret = -EINVAL;
8480d163575Sopenharmony_ci            goto EXIT;
8490d163575Sopenharmony_ci        }
8500d163575Sopenharmony_ci        if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) {
8510d163575Sopenharmony_ci            ret = -EINVAL;
8520d163575Sopenharmony_ci            goto EXIT;
8530d163575Sopenharmony_ci        }
8540d163575Sopenharmony_ci        obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]);
8550d163575Sopenharmony_ci        if (obj == NULL) {
8560d163575Sopenharmony_ci            ret = -EINVAL;
8570d163575Sopenharmony_ci            goto EXIT;
8580d163575Sopenharmony_ci        }
8590d163575Sopenharmony_ci        ret = HandleObj(dstTid, obj, FALSE);
8600d163575Sopenharmony_ci        if (ret != LOS_OK) {
8610d163575Sopenharmony_ci            goto EXIT;
8620d163575Sopenharmony_ci        }
8630d163575Sopenharmony_ci    }
8640d163575Sopenharmony_ci    return LOS_OK;
8650d163575Sopenharmony_ciEXIT:
8660d163575Sopenharmony_ci    for (i--; i >= 0; i--) {
8670d163575Sopenharmony_ci        obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]);
8680d163575Sopenharmony_ci        (VOID)HandleObj(dstTid, obj, TRUE);
8690d163575Sopenharmony_ci    }
8700d163575Sopenharmony_ci    return ret;
8710d163575Sopenharmony_ci}
8720d163575Sopenharmony_ci
8730d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckMsgSize(IpcMsg *msg)
8740d163575Sopenharmony_ci{
8750d163575Sopenharmony_ci    UINT64 totalSize;
8760d163575Sopenharmony_ci    UINT32 i;
8770d163575Sopenharmony_ci    UINT32 *offset = (UINT32 *)(UINTPTR)(msg->offsets);
8780d163575Sopenharmony_ci    SpecialObj *obj = NULL;
8790d163575Sopenharmony_ci    if (msg->target.handle != 0) {
8800d163575Sopenharmony_ci        return LOS_OK;
8810d163575Sopenharmony_ci    }
8820d163575Sopenharmony_ci    /* msg send to cms, check the msg size */
8830d163575Sopenharmony_ci    totalSize = (UINT64)sizeof(IpcMsg) + msg->dataSz + msg->spObjNum * sizeof(UINT32);
8840d163575Sopenharmony_ci    for (i = 0; i < msg->spObjNum; i++) {
8850d163575Sopenharmony_ci        if (offset[i] > msg->dataSz - sizeof(SpecialObj)) {
8860d163575Sopenharmony_ci            return -EINVAL;
8870d163575Sopenharmony_ci        }
8880d163575Sopenharmony_ci        if ((i > 0) && (offset[i] < offset[i - 1] + sizeof(SpecialObj))) {
8890d163575Sopenharmony_ci            return -EINVAL;
8900d163575Sopenharmony_ci        }
8910d163575Sopenharmony_ci        obj = (SpecialObj *)((UINTPTR)msg->data + offset[i]);
8920d163575Sopenharmony_ci        if (obj == NULL) {
8930d163575Sopenharmony_ci            return -EINVAL;
8940d163575Sopenharmony_ci        }
8950d163575Sopenharmony_ci        if (obj->type == OBJ_PTR) {
8960d163575Sopenharmony_ci            totalSize += obj->content.ptr.buffSz;
8970d163575Sopenharmony_ci        }
8980d163575Sopenharmony_ci    }
8990d163575Sopenharmony_ci    (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
9000d163575Sopenharmony_ci    if (totalSize > g_cmsTask.maxMsgSize) {
9010d163575Sopenharmony_ci        (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
9020d163575Sopenharmony_ci        return -EINVAL;
9030d163575Sopenharmony_ci    }
9040d163575Sopenharmony_ci    (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
9050d163575Sopenharmony_ci    return LOS_OK;
9060d163575Sopenharmony_ci}
9070d163575Sopenharmony_ci
9080d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CopyDataFromUser(IpcListNode *node, UINT32 bufSz, const IpcMsg *msg)
9090d163575Sopenharmony_ci{
9100d163575Sopenharmony_ci    UINT32 ret;
9110d163575Sopenharmony_ci    ret = (UINT32)memcpy_s((VOID *)(&node->msg), bufSz - sizeof(LOS_DL_LIST), (const VOID *)msg, sizeof(IpcMsg));
9120d163575Sopenharmony_ci    if (ret != LOS_OK) {
9130d163575Sopenharmony_ci        PRINT_DEBUG("%s, %d, %u\n", __FUNCTION__, __LINE__, ret);
9140d163575Sopenharmony_ci        return ret;
9150d163575Sopenharmony_ci    }
9160d163575Sopenharmony_ci
9170d163575Sopenharmony_ci    if (msg->dataSz) {
9180d163575Sopenharmony_ci        node->msg.data = (VOID *)((UINTPTR)node + sizeof(IpcListNode));
9190d163575Sopenharmony_ci        ret = copy_from_user((VOID *)(node->msg.data), msg->data, msg->dataSz);
9200d163575Sopenharmony_ci        if (ret != LOS_OK) {
9210d163575Sopenharmony_ci            PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__);
9220d163575Sopenharmony_ci            return ret;
9230d163575Sopenharmony_ci        }
9240d163575Sopenharmony_ci    } else {
9250d163575Sopenharmony_ci        node->msg.data = NULL;
9260d163575Sopenharmony_ci    }
9270d163575Sopenharmony_ci
9280d163575Sopenharmony_ci    if (msg->spObjNum) {
9290d163575Sopenharmony_ci        node->msg.offsets = (VOID *)((UINTPTR)node + sizeof(IpcListNode) + msg->dataSz);
9300d163575Sopenharmony_ci        ret = copy_from_user((VOID *)(node->msg.offsets), msg->offsets, msg->spObjNum * sizeof(UINT32));
9310d163575Sopenharmony_ci        if (ret != LOS_OK) {
9320d163575Sopenharmony_ci            PRINT_DEBUG("%s, %d, %x, %x, %d\n", __FUNCTION__, __LINE__, node->msg.offsets, msg->offsets, msg->spObjNum);
9330d163575Sopenharmony_ci            return ret;
9340d163575Sopenharmony_ci        }
9350d163575Sopenharmony_ci    } else {
9360d163575Sopenharmony_ci        node->msg.offsets = NULL;
9370d163575Sopenharmony_ci    }
9380d163575Sopenharmony_ci    ret = CheckMsgSize(&node->msg);
9390d163575Sopenharmony_ci    if (ret != LOS_OK) {
9400d163575Sopenharmony_ci        PRINT_DEBUG("%s, %d\n", __FUNCTION__, __LINE__);
9410d163575Sopenharmony_ci        return ret;
9420d163575Sopenharmony_ci    }
9430d163575Sopenharmony_ci    node->msg.taskID = LOS_CurTaskIDGet();
9440d163575Sopenharmony_ci    node->msg.processID = OsCurrProcessGet()->processID;
9450d163575Sopenharmony_ci#ifdef LOSCFG_SECURITY_CAPABILITY
9460d163575Sopenharmony_ci    node->msg.userID = OsCurrProcessGet()->user->userID;
9470d163575Sopenharmony_ci    node->msg.gid = OsCurrProcessGet()->user->gid;
9480d163575Sopenharmony_ci#endif
9490d163575Sopenharmony_ci    return LOS_OK;
9500d163575Sopenharmony_ci}
9510d163575Sopenharmony_ci
9520d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC BOOL IsValidReply(const IpcContent *content)
9530d163575Sopenharmony_ci{
9540d163575Sopenharmony_ci    LosProcessCB *curr = OsCurrProcessGet();
9550d163575Sopenharmony_ci    IpcListNode *node = (IpcListNode *)GetIpcKernelAddr(curr, (INTPTR)(content->buffToFree));
9560d163575Sopenharmony_ci    IpcMsg *requestMsg = &node->msg;
9570d163575Sopenharmony_ci    IpcMsg *replyMsg = content->outMsg;
9580d163575Sopenharmony_ci    UINT32 reqDstTid = 0;
9590d163575Sopenharmony_ci    /* Check whether the reply matches the request */
9600d163575Sopenharmony_ci    if ((requestMsg->type != MT_REQUEST)  ||
9610d163575Sopenharmony_ci        (requestMsg->flag == LITEIPC_FLAG_ONEWAY) ||
9620d163575Sopenharmony_ci        (replyMsg->timestamp != requestMsg->timestamp) ||
9630d163575Sopenharmony_ci        (replyMsg->target.handle != requestMsg->taskID) ||
9640d163575Sopenharmony_ci        (GetTid(requestMsg->target.handle, &reqDstTid) != 0) ||
9650d163575Sopenharmony_ci        (OS_TCB_FROM_TID(reqDstTid)->processCB != (UINTPTR)curr)) {
9660d163575Sopenharmony_ci        return FALSE;
9670d163575Sopenharmony_ci    }
9680d163575Sopenharmony_ci    return TRUE;
9690d163575Sopenharmony_ci}
9700d163575Sopenharmony_ci
9710d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckPara(IpcContent *content, UINT32 *dstTid)
9720d163575Sopenharmony_ci{
9730d163575Sopenharmony_ci    UINT32 ret;
9740d163575Sopenharmony_ci    IpcMsg *msg = content->outMsg;
9750d163575Sopenharmony_ci    UINT32 flag = content->flag;
9760d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1)
9770d163575Sopenharmony_ci    UINT64 now = LOS_CurrNanosec();
9780d163575Sopenharmony_ci#endif
9790d163575Sopenharmony_ci    if (((msg->dataSz > 0) && (msg->data == NULL)) ||
9800d163575Sopenharmony_ci        ((msg->spObjNum > 0) && (msg->offsets == NULL)) ||
9810d163575Sopenharmony_ci        (msg->dataSz > IPC_MSG_DATA_SZ_MAX) ||
9820d163575Sopenharmony_ci        (msg->spObjNum > IPC_MSG_OBJECT_NUM_MAX) ||
9830d163575Sopenharmony_ci        (msg->dataSz < msg->spObjNum * sizeof(SpecialObj))) {
9840d163575Sopenharmony_ci        return -EINVAL;
9850d163575Sopenharmony_ci    }
9860d163575Sopenharmony_ci    switch (msg->type) {
9870d163575Sopenharmony_ci        case MT_REQUEST:
9880d163575Sopenharmony_ci            if (HasServiceAccess(msg->target.handle)) {
9890d163575Sopenharmony_ci                ret = GetTid(msg->target.handle, dstTid);
9900d163575Sopenharmony_ci                if (ret != LOS_OK) {
9910d163575Sopenharmony_ci                    return -EINVAL;
9920d163575Sopenharmony_ci                }
9930d163575Sopenharmony_ci            } else {
9940d163575Sopenharmony_ci                PRINT_ERR("Liteipc %s, %d\n", __FUNCTION__, __LINE__);
9950d163575Sopenharmony_ci                return -EACCES;
9960d163575Sopenharmony_ci            }
9970d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1)
9980d163575Sopenharmony_ci            msg->timestamp = now;
9990d163575Sopenharmony_ci#endif
10000d163575Sopenharmony_ci            break;
10010d163575Sopenharmony_ci        case MT_REPLY:
10020d163575Sopenharmony_ci        case MT_FAILED_REPLY:
10030d163575Sopenharmony_ci            if ((flag & BUFF_FREE) != BUFF_FREE) {
10040d163575Sopenharmony_ci                return -EINVAL;
10050d163575Sopenharmony_ci            }
10060d163575Sopenharmony_ci            if (!IsValidReply(content)) {
10070d163575Sopenharmony_ci                return -EINVAL;
10080d163575Sopenharmony_ci            }
10090d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1)
10100d163575Sopenharmony_ci            if (now > msg->timestamp + LITEIPC_TIMEOUT_NS) {
10110d163575Sopenharmony_ci#ifdef LOSCFG_KERNEL_HOOK
10120d163575Sopenharmony_ci                ret = GetTid(msg->target.handle, dstTid);
10130d163575Sopenharmony_ci                if (ret != LOS_OK) {
10140d163575Sopenharmony_ci                    *dstTid = INVAILD_ID;
10150d163575Sopenharmony_ci                }
10160d163575Sopenharmony_ci#endif
10170d163575Sopenharmony_ci                OsHookCall(LOS_HOOK_TYPE_IPC_WRITE_DROP, msg, *dstTid,
10180d163575Sopenharmony_ci                           (*dstTid == INVAILD_ID) ? INVAILD_ID : OS_PCB_FROM_TID(*dstTid)->processID, 0);
10190d163575Sopenharmony_ci                PRINT_ERR("Liteipc A timeout reply, request timestamp:%lld, now:%lld\n", msg->timestamp, now);
10200d163575Sopenharmony_ci                return -ETIME;
10210d163575Sopenharmony_ci            }
10220d163575Sopenharmony_ci#endif
10230d163575Sopenharmony_ci            *dstTid = msg->target.handle;
10240d163575Sopenharmony_ci            break;
10250d163575Sopenharmony_ci        case MT_DEATH_NOTIFY:
10260d163575Sopenharmony_ci            *dstTid = msg->target.handle;
10270d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1)
10280d163575Sopenharmony_ci            msg->timestamp = now;
10290d163575Sopenharmony_ci#endif
10300d163575Sopenharmony_ci            break;
10310d163575Sopenharmony_ci        default:
10320d163575Sopenharmony_ci            PRINT_DEBUG("Unknown msg type:%d\n", msg->type);
10330d163575Sopenharmony_ci            return -EINVAL;
10340d163575Sopenharmony_ci    }
10350d163575Sopenharmony_ci
10360d163575Sopenharmony_ci    if (IsTaskAlive(*dstTid) == FALSE) {
10370d163575Sopenharmony_ci        return -EINVAL;
10380d163575Sopenharmony_ci    }
10390d163575Sopenharmony_ci    return LOS_OK;
10400d163575Sopenharmony_ci}
10410d163575Sopenharmony_ci
10420d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcWrite(IpcContent *content)
10430d163575Sopenharmony_ci{
10440d163575Sopenharmony_ci    UINT32 ret, intSave;
10450d163575Sopenharmony_ci    UINT32 dstTid;
10460d163575Sopenharmony_ci
10470d163575Sopenharmony_ci    IpcMsg *msg = content->outMsg;
10480d163575Sopenharmony_ci
10490d163575Sopenharmony_ci    ret = CheckPara(content, &dstTid);
10500d163575Sopenharmony_ci    if (ret != LOS_OK) {
10510d163575Sopenharmony_ci        return ret;
10520d163575Sopenharmony_ci    }
10530d163575Sopenharmony_ci
10540d163575Sopenharmony_ci    LosTaskCB *tcb = OS_TCB_FROM_TID(dstTid);
10550d163575Sopenharmony_ci    LosProcessCB *pcb = OS_PCB_FROM_TCB(tcb);
10560d163575Sopenharmony_ci    if (pcb->ipcInfo == NULL) {
10570d163575Sopenharmony_ci        PRINT_ERR("pid %u Liteipc not create\n", pcb->processID);
10580d163575Sopenharmony_ci        return -EINVAL;
10590d163575Sopenharmony_ci    }
10600d163575Sopenharmony_ci
10610d163575Sopenharmony_ci    UINT32 bufSz = sizeof(IpcListNode) + msg->dataSz + msg->spObjNum * sizeof(UINT32);
10620d163575Sopenharmony_ci    IpcListNode *buf = (IpcListNode *)LiteIpcNodeAlloc(pcb, bufSz);
10630d163575Sopenharmony_ci    if (buf == NULL) {
10640d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
10650d163575Sopenharmony_ci        return -ENOMEM;
10660d163575Sopenharmony_ci    }
10670d163575Sopenharmony_ci    ret = CopyDataFromUser(buf, bufSz, (const IpcMsg *)msg);
10680d163575Sopenharmony_ci    if (ret != LOS_OK) {
10690d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
10700d163575Sopenharmony_ci        goto ERROR_COPY;
10710d163575Sopenharmony_ci    }
10720d163575Sopenharmony_ci
10730d163575Sopenharmony_ci    if (tcb->ipcTaskInfo == NULL) {
10740d163575Sopenharmony_ci        tcb->ipcTaskInfo = LiteIpcTaskInit();
10750d163575Sopenharmony_ci    }
10760d163575Sopenharmony_ci
10770d163575Sopenharmony_ci    ret = HandleSpecialObjects(dstTid, buf, FALSE);
10780d163575Sopenharmony_ci    if (ret != LOS_OK) {
10790d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
10800d163575Sopenharmony_ci        goto ERROR_COPY;
10810d163575Sopenharmony_ci    }
10820d163575Sopenharmony_ci    /* add data to list and wake up dest task */
10830d163575Sopenharmony_ci    SCHEDULER_LOCK(intSave);
10840d163575Sopenharmony_ci    LOS_ListTailInsert(&(tcb->ipcTaskInfo->msgListHead), &(buf->listNode));
10850d163575Sopenharmony_ci    OsHookCall(LOS_HOOK_TYPE_IPC_WRITE, &buf->msg, dstTid, pcb->processID, tcb->waitFlag);
10860d163575Sopenharmony_ci    if (tcb->waitFlag == OS_TASK_WAIT_LITEIPC) {
10870d163575Sopenharmony_ci        OsTaskWakeClearPendMask(tcb);
10880d163575Sopenharmony_ci        tcb->ops->wake(tcb);
10890d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
10900d163575Sopenharmony_ci        LOS_MpSchedule(OS_MP_CPU_ALL);
10910d163575Sopenharmony_ci        LOS_Schedule();
10920d163575Sopenharmony_ci    } else {
10930d163575Sopenharmony_ci        SCHEDULER_UNLOCK(intSave);
10940d163575Sopenharmony_ci    }
10950d163575Sopenharmony_ci    return LOS_OK;
10960d163575Sopenharmony_ciERROR_COPY:
10970d163575Sopenharmony_ci    LiteIpcNodeFree(pcb, buf);
10980d163575Sopenharmony_ci    return ret;
10990d163575Sopenharmony_ci}
11000d163575Sopenharmony_ci
11010d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 CheckReceivedMsg(IpcListNode *node, IpcContent *content, LosTaskCB *tcb)
11020d163575Sopenharmony_ci{
11030d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
11040d163575Sopenharmony_ci    if (node == NULL) {
11050d163575Sopenharmony_ci        return -EINVAL;
11060d163575Sopenharmony_ci    }
11070d163575Sopenharmony_ci    switch (node->msg.type) {
11080d163575Sopenharmony_ci        case MT_REQUEST:
11090d163575Sopenharmony_ci            if ((content->flag & SEND) == SEND) {
11100d163575Sopenharmony_ci                PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
11110d163575Sopenharmony_ci                ret = -EINVAL;
11120d163575Sopenharmony_ci            }
11130d163575Sopenharmony_ci            break;
11140d163575Sopenharmony_ci        case MT_FAILED_REPLY:
11150d163575Sopenharmony_ci            ret = -ENOENT;
11160d163575Sopenharmony_ci            /* fall-through */
11170d163575Sopenharmony_ci        case MT_REPLY:
11180d163575Sopenharmony_ci            if ((content->flag & SEND) != SEND) {
11190d163575Sopenharmony_ci                PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
11200d163575Sopenharmony_ci                ret = -EINVAL;
11210d163575Sopenharmony_ci            }
11220d163575Sopenharmony_ci#if (USE_TIMESTAMP == 1)
11230d163575Sopenharmony_ci            if (node->msg.timestamp != content->outMsg->timestamp) {
11240d163575Sopenharmony_ci                PRINT_ERR("Receive a unmatch reply, drop it\n");
11250d163575Sopenharmony_ci                ret = -EINVAL;
11260d163575Sopenharmony_ci            }
11270d163575Sopenharmony_ci#else
11280d163575Sopenharmony_ci            if ((node->msg.code != content->outMsg->code) ||
11290d163575Sopenharmony_ci                (node->msg.target.token != content->outMsg->target.token)) {
11300d163575Sopenharmony_ci                PRINT_ERR("Receive a unmatch reply, drop it\n");
11310d163575Sopenharmony_ci                ret = -EINVAL;
11320d163575Sopenharmony_ci            }
11330d163575Sopenharmony_ci#endif
11340d163575Sopenharmony_ci            break;
11350d163575Sopenharmony_ci        case MT_DEATH_NOTIFY:
11360d163575Sopenharmony_ci            break;
11370d163575Sopenharmony_ci        default:
11380d163575Sopenharmony_ci            PRINT_ERR("Unknown msg type:%d\n", node->msg.type);
11390d163575Sopenharmony_ci            ret =  -EINVAL;
11400d163575Sopenharmony_ci    }
11410d163575Sopenharmony_ci    if (ret != LOS_OK) {
11420d163575Sopenharmony_ci        OsHookCall(LOS_HOOK_TYPE_IPC_READ_DROP, &node->msg, tcb->waitFlag);
11430d163575Sopenharmony_ci        (VOID)HandleSpecialObjects(LOS_CurTaskIDGet(), node, TRUE);
11440d163575Sopenharmony_ci        (VOID)LiteIpcNodeFree(OsCurrProcessGet(), (VOID *)node);
11450d163575Sopenharmony_ci    } else {
11460d163575Sopenharmony_ci        OsHookCall(LOS_HOOK_TYPE_IPC_READ, &node->msg, tcb->waitFlag);
11470d163575Sopenharmony_ci    }
11480d163575Sopenharmony_ci    return ret;
11490d163575Sopenharmony_ci}
11500d163575Sopenharmony_ci
11510d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcRead(IpcContent *content)
11520d163575Sopenharmony_ci{
11530d163575Sopenharmony_ci    UINT32 intSave, ret;
11540d163575Sopenharmony_ci    UINT32 selfTid = LOS_CurTaskIDGet();
11550d163575Sopenharmony_ci    LOS_DL_LIST *listHead = NULL;
11560d163575Sopenharmony_ci    LOS_DL_LIST *listNode = NULL;
11570d163575Sopenharmony_ci    IpcListNode *node = NULL;
11580d163575Sopenharmony_ci    UINT32 syncFlag = (content->flag & SEND) && (content->flag & RECV);
11590d163575Sopenharmony_ci    UINT32 timeout = syncFlag ? LOS_MS2Tick(LITEIPC_TIMEOUT_MS) : LOS_WAIT_FOREVER;
11600d163575Sopenharmony_ci
11610d163575Sopenharmony_ci    LosTaskCB *tcb = OS_TCB_FROM_TID(selfTid);
11620d163575Sopenharmony_ci    if (tcb->ipcTaskInfo == NULL) {
11630d163575Sopenharmony_ci        tcb->ipcTaskInfo = LiteIpcTaskInit();
11640d163575Sopenharmony_ci    }
11650d163575Sopenharmony_ci
11660d163575Sopenharmony_ci    listHead = &(tcb->ipcTaskInfo->msgListHead);
11670d163575Sopenharmony_ci    do {
11680d163575Sopenharmony_ci        SCHEDULER_LOCK(intSave);
11690d163575Sopenharmony_ci        if (LOS_ListEmpty(listHead)) {
11700d163575Sopenharmony_ci            OsTaskWaitSetPendMask(OS_TASK_WAIT_LITEIPC, OS_INVALID_VALUE, timeout);
11710d163575Sopenharmony_ci            OsHookCall(LOS_HOOK_TYPE_IPC_TRY_READ, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag);
11720d163575Sopenharmony_ci            ret = tcb->ops->wait(tcb, &g_ipcPendlist, timeout);
11730d163575Sopenharmony_ci            if (ret == LOS_ERRNO_TSK_TIMEOUT) {
11740d163575Sopenharmony_ci                OsHookCall(LOS_HOOK_TYPE_IPC_READ_TIMEOUT, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag);
11750d163575Sopenharmony_ci                SCHEDULER_UNLOCK(intSave);
11760d163575Sopenharmony_ci                return -ETIME;
11770d163575Sopenharmony_ci            }
11780d163575Sopenharmony_ci
11790d163575Sopenharmony_ci            if (OsTaskIsKilled(tcb)) {
11800d163575Sopenharmony_ci                OsHookCall(LOS_HOOK_TYPE_IPC_KILL, syncFlag ? MT_REPLY : MT_REQUEST, tcb->waitFlag);
11810d163575Sopenharmony_ci                SCHEDULER_UNLOCK(intSave);
11820d163575Sopenharmony_ci                return -ERFKILL;
11830d163575Sopenharmony_ci            }
11840d163575Sopenharmony_ci
11850d163575Sopenharmony_ci            SCHEDULER_UNLOCK(intSave);
11860d163575Sopenharmony_ci        } else {
11870d163575Sopenharmony_ci            listNode = LOS_DL_LIST_FIRST(listHead);
11880d163575Sopenharmony_ci            LOS_ListDelete(listNode);
11890d163575Sopenharmony_ci            node = LOS_DL_LIST_ENTRY(listNode, IpcListNode, listNode);
11900d163575Sopenharmony_ci            SCHEDULER_UNLOCK(intSave);
11910d163575Sopenharmony_ci            ret = CheckReceivedMsg(node, content, tcb);
11920d163575Sopenharmony_ci            if (ret == LOS_OK) {
11930d163575Sopenharmony_ci                break;
11940d163575Sopenharmony_ci            }
11950d163575Sopenharmony_ci            if (ret == -ENOENT) { /* It means that we've received a failed reply */
11960d163575Sopenharmony_ci                return ret;
11970d163575Sopenharmony_ci            }
11980d163575Sopenharmony_ci        }
11990d163575Sopenharmony_ci    } while (1);
12000d163575Sopenharmony_ci    node->msg.data = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.data));
12010d163575Sopenharmony_ci    node->msg.offsets = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(node->msg.offsets));
12020d163575Sopenharmony_ci    content->inMsg = (VOID *)GetIpcUserAddr(OsCurrProcessGet(), (INTPTR)(&(node->msg)));
12030d163575Sopenharmony_ci    EnableIpcNodeFreeByUser(OsCurrProcessGet(), (VOID *)node);
12040d163575Sopenharmony_ci    return LOS_OK;
12050d163575Sopenharmony_ci}
12060d163575Sopenharmony_ci
12070d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 LiteIpcMsgHandle(IpcContent *con)
12080d163575Sopenharmony_ci{
12090d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
12100d163575Sopenharmony_ci    IpcContent localContent;
12110d163575Sopenharmony_ci    IpcContent *content = &localContent;
12120d163575Sopenharmony_ci    IpcMsg localMsg;
12130d163575Sopenharmony_ci    IpcMsg *msg = &localMsg;
12140d163575Sopenharmony_ci    IpcListNode *nodeNeedFree = NULL;
12150d163575Sopenharmony_ci
12160d163575Sopenharmony_ci    if (copy_from_user((void *)content, (const void *)con, sizeof(IpcContent)) != LOS_OK) {
12170d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
12180d163575Sopenharmony_ci        return -EINVAL;
12190d163575Sopenharmony_ci    }
12200d163575Sopenharmony_ci
12210d163575Sopenharmony_ci    if ((content->flag & BUFF_FREE) == BUFF_FREE) {
12220d163575Sopenharmony_ci        ret = CheckUsedBuffer(content->buffToFree, &nodeNeedFree);
12230d163575Sopenharmony_ci        if (ret != LOS_OK) {
12240d163575Sopenharmony_ci            PRINT_ERR("CheckUsedBuffer failed:%d\n", ret);
12250d163575Sopenharmony_ci            return ret;
12260d163575Sopenharmony_ci        }
12270d163575Sopenharmony_ci    }
12280d163575Sopenharmony_ci
12290d163575Sopenharmony_ci    if ((content->flag & SEND) == SEND) {
12300d163575Sopenharmony_ci        if (content->outMsg == NULL) {
12310d163575Sopenharmony_ci            PRINT_ERR("content->outmsg is null\n");
12320d163575Sopenharmony_ci            ret = -EINVAL;
12330d163575Sopenharmony_ci            goto BUFFER_FREE;
12340d163575Sopenharmony_ci        }
12350d163575Sopenharmony_ci        if (copy_from_user((void *)msg, (const void *)content->outMsg, sizeof(IpcMsg)) != LOS_OK) {
12360d163575Sopenharmony_ci            PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
12370d163575Sopenharmony_ci            ret = -EINVAL;
12380d163575Sopenharmony_ci            goto BUFFER_FREE;
12390d163575Sopenharmony_ci        }
12400d163575Sopenharmony_ci        content->outMsg = msg;
12410d163575Sopenharmony_ci        if ((content->outMsg->type < 0) || (content->outMsg->type >= MT_DEATH_NOTIFY)) {
12420d163575Sopenharmony_ci            PRINT_ERR("LiteIpc unknown msg type:%d\n", content->outMsg->type);
12430d163575Sopenharmony_ci            ret = -EINVAL;
12440d163575Sopenharmony_ci            goto BUFFER_FREE;
12450d163575Sopenharmony_ci        }
12460d163575Sopenharmony_ci        ret = LiteIpcWrite(content);
12470d163575Sopenharmony_ci        if (ret != LOS_OK) {
12480d163575Sopenharmony_ci            PRINT_ERR("LiteIpcWrite failed\n");
12490d163575Sopenharmony_ci            goto BUFFER_FREE;
12500d163575Sopenharmony_ci        }
12510d163575Sopenharmony_ci    }
12520d163575Sopenharmony_ciBUFFER_FREE:
12530d163575Sopenharmony_ci    if (nodeNeedFree != NULL) {
12540d163575Sopenharmony_ci        UINT32 freeRet = LiteIpcNodeFree(OsCurrProcessGet(), nodeNeedFree);
12550d163575Sopenharmony_ci        ret = (freeRet == LOS_OK) ? ret : freeRet;
12560d163575Sopenharmony_ci    }
12570d163575Sopenharmony_ci    if (ret != LOS_OK) {
12580d163575Sopenharmony_ci        return ret;
12590d163575Sopenharmony_ci    }
12600d163575Sopenharmony_ci
12610d163575Sopenharmony_ci    if ((content->flag & RECV) == RECV) {
12620d163575Sopenharmony_ci        ret = LiteIpcRead(content);
12630d163575Sopenharmony_ci        if (ret != LOS_OK) {
12640d163575Sopenharmony_ci            PRINT_ERR("LiteIpcRead failed ERROR: %d\n", (INT32)ret);
12650d163575Sopenharmony_ci            return ret;
12660d163575Sopenharmony_ci        }
12670d163575Sopenharmony_ci        UINT32 offset = LOS_OFF_SET_OF(IpcContent, inMsg);
12680d163575Sopenharmony_ci        ret = copy_to_user((char*)con + offset, (char*)content + offset, sizeof(IpcMsg *));
12690d163575Sopenharmony_ci        if (ret != LOS_OK) {
12700d163575Sopenharmony_ci            PRINT_ERR("%s, %d, %d\n", __FUNCTION__, __LINE__, ret);
12710d163575Sopenharmony_ci            return -EINVAL;
12720d163575Sopenharmony_ci        }
12730d163575Sopenharmony_ci    }
12740d163575Sopenharmony_ci    return ret;
12750d163575Sopenharmony_ci}
12760d163575Sopenharmony_ci
12770d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleCmsCmd(CmsCmdContent *content)
12780d163575Sopenharmony_ci{
12790d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
12800d163575Sopenharmony_ci    CmsCmdContent localContent;
12810d163575Sopenharmony_ci    if (content == NULL) {
12820d163575Sopenharmony_ci        return -EINVAL;
12830d163575Sopenharmony_ci    }
12840d163575Sopenharmony_ci    if (IsCmsTask(LOS_CurTaskIDGet()) == FALSE) {
12850d163575Sopenharmony_ci        return -EACCES;
12860d163575Sopenharmony_ci    }
12870d163575Sopenharmony_ci    if (copy_from_user((void *)(&localContent), (const void *)content, sizeof(CmsCmdContent)) != LOS_OK) {
12880d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
12890d163575Sopenharmony_ci        return -EINVAL;
12900d163575Sopenharmony_ci    }
12910d163575Sopenharmony_ci    switch (localContent.cmd) {
12920d163575Sopenharmony_ci        case CMS_GEN_HANDLE:
12930d163575Sopenharmony_ci            if ((localContent.taskID != 0) && (IsTaskAlive(localContent.taskID) == FALSE)) {
12940d163575Sopenharmony_ci                return -EINVAL;
12950d163575Sopenharmony_ci            }
12960d163575Sopenharmony_ci            ret = GenerateServiceHandle(localContent.taskID, HANDLE_REGISTED, &(localContent.serviceHandle));
12970d163575Sopenharmony_ci            if (ret == LOS_OK) {
12980d163575Sopenharmony_ci                ret = copy_to_user((void *)content, (const void *)(&localContent), sizeof(CmsCmdContent));
12990d163575Sopenharmony_ci            }
13000d163575Sopenharmony_ci            (VOID)LOS_MuxLock(&g_serviceHandleMapMux, LOS_WAIT_FOREVER);
13010d163575Sopenharmony_ci            AddServiceAccess(g_cmsTask.taskID, localContent.serviceHandle);
13020d163575Sopenharmony_ci            (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
13030d163575Sopenharmony_ci            break;
13040d163575Sopenharmony_ci        case CMS_REMOVE_HANDLE:
13050d163575Sopenharmony_ci            if (localContent.serviceHandle >= MAX_SERVICE_NUM) {
13060d163575Sopenharmony_ci                return -EINVAL;
13070d163575Sopenharmony_ci            }
13080d163575Sopenharmony_ci            RefreshServiceHandle(localContent.serviceHandle, -1);
13090d163575Sopenharmony_ci            break;
13100d163575Sopenharmony_ci        case CMS_ADD_ACCESS:
13110d163575Sopenharmony_ci            if (IsTaskAlive(localContent.taskID) == FALSE) {
13120d163575Sopenharmony_ci                return -EINVAL;
13130d163575Sopenharmony_ci            }
13140d163575Sopenharmony_ci            return AddServiceAccess(localContent.taskID, localContent.serviceHandle);
13150d163575Sopenharmony_ci        default:
13160d163575Sopenharmony_ci            PRINT_DEBUG("Unknown cmd cmd:%d\n", localContent.cmd);
13170d163575Sopenharmony_ci            return -EINVAL;
13180d163575Sopenharmony_ci    }
13190d163575Sopenharmony_ci    return ret;
13200d163575Sopenharmony_ci}
13210d163575Sopenharmony_ci
13220d163575Sopenharmony_ciLITE_OS_SEC_TEXT STATIC UINT32 HandleGetVersion(IpcVersion *version)
13230d163575Sopenharmony_ci{
13240d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
13250d163575Sopenharmony_ci    IpcVersion localIpcVersion;
13260d163575Sopenharmony_ci    if (version == NULL) {
13270d163575Sopenharmony_ci        return -EINVAL;
13280d163575Sopenharmony_ci    }
13290d163575Sopenharmony_ci
13300d163575Sopenharmony_ci    localIpcVersion.driverVersion = DRIVER_VERSION;
13310d163575Sopenharmony_ci    ret = copy_to_user((void *)version, (const void *)(&localIpcVersion), sizeof(IpcVersion));
13320d163575Sopenharmony_ci    if (ret != LOS_OK) {
13330d163575Sopenharmony_ci        PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
13340d163575Sopenharmony_ci    }
13350d163575Sopenharmony_ci    return ret;
13360d163575Sopenharmony_ci}
13370d163575Sopenharmony_ci
13380d163575Sopenharmony_ciLITE_OS_SEC_TEXT int LiteIpcIoctl(struct file *filep, int cmd, unsigned long arg)
13390d163575Sopenharmony_ci{
13400d163575Sopenharmony_ci    UINT32 ret = LOS_OK;
13410d163575Sopenharmony_ci    LosProcessCB *pcb = OsCurrProcessGet();
13420d163575Sopenharmony_ci    ProcIpcInfo *ipcInfo = pcb->ipcInfo;
13430d163575Sopenharmony_ci
13440d163575Sopenharmony_ci    if (ipcInfo == NULL) {
13450d163575Sopenharmony_ci        PRINT_ERR("Liteipc pool not create!\n");
13460d163575Sopenharmony_ci        return -EINVAL;
13470d163575Sopenharmony_ci    }
13480d163575Sopenharmony_ci
13490d163575Sopenharmony_ci    if (IsPoolMapped(ipcInfo) == FALSE) {
13500d163575Sopenharmony_ci        PRINT_ERR("Liteipc Ipc pool not init, need to mmap first!\n");
13510d163575Sopenharmony_ci        return -ENOMEM;
13520d163575Sopenharmony_ci    }
13530d163575Sopenharmony_ci
13540d163575Sopenharmony_ci    switch (cmd) {
13550d163575Sopenharmony_ci        case IPC_SET_CMS:
13560d163575Sopenharmony_ci            return (INT32)SetCms(arg);
13570d163575Sopenharmony_ci        case IPC_CMS_CMD:
13580d163575Sopenharmony_ci            return (INT32)HandleCmsCmd((CmsCmdContent *)(UINTPTR)arg);
13590d163575Sopenharmony_ci        case IPC_GET_VERSION:
13600d163575Sopenharmony_ci            return (INT32)HandleGetVersion((IpcVersion *)(UINTPTR)arg);
13610d163575Sopenharmony_ci        case IPC_SET_IPC_THREAD:
13620d163575Sopenharmony_ci            if (IsCmsSet() == FALSE) {
13630d163575Sopenharmony_ci                PRINT_ERR("Liteipc ServiceManager not set!\n");
13640d163575Sopenharmony_ci                return -EINVAL;
13650d163575Sopenharmony_ci            }
13660d163575Sopenharmony_ci            return (INT32)SetIpcTask();
13670d163575Sopenharmony_ci        case IPC_SEND_RECV_MSG:
13680d163575Sopenharmony_ci            if (arg == 0) {
13690d163575Sopenharmony_ci                return -EINVAL;
13700d163575Sopenharmony_ci            }
13710d163575Sopenharmony_ci            if (IsCmsSet() == FALSE) {
13720d163575Sopenharmony_ci                PRINT_ERR("Liteipc ServiceManager not set!\n");
13730d163575Sopenharmony_ci                return -EINVAL;
13740d163575Sopenharmony_ci            }
13750d163575Sopenharmony_ci            ret = LiteIpcMsgHandle((IpcContent *)(UINTPTR)arg);
13760d163575Sopenharmony_ci            if (ret != LOS_OK) {
13770d163575Sopenharmony_ci                return (INT32)ret;
13780d163575Sopenharmony_ci            }
13790d163575Sopenharmony_ci            break;
13800d163575Sopenharmony_ci        default:
13810d163575Sopenharmony_ci            PRINT_ERR("Unknown liteipc ioctl cmd:%d\n", cmd);
13820d163575Sopenharmony_ci            return -EINVAL;
13830d163575Sopenharmony_ci    }
13840d163575Sopenharmony_ci    return (INT32)ret;
13850d163575Sopenharmony_ci}
1386