OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(二)

61 阅读5分钟

函数实现详解

注册syscap
/*
    函数功能:添加syscap
    函数参数:@endpoint:当前进程的通信端点
             @sysCap:syscap的name
             @isReg:标识是否注册
    函数返回:添加成功 返回EC_SUCCESS 添加失败 返回EC_INVALID
    函数描述:将syscap的信息通过IPC的方式发送到主endpoint,完成添加操作。
*/
int32 SAMGR_AddSysCap(const Endpoint *endpoint, const char *sysCap, BOOL isReg)
{
    if (endpoint == NULL)
    {
        return EC_INVALID;
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap begin");
    //定义请求结构
    IpcIo req;
    uint8 data[MAX_DATA_LEN];
    //初始化,将req与data关联
    IpcIoInit(&req, data, MAX_DATA_LEN, 0);
    //将消息放入共享内存,内容为RES_SYSCAP
    IpcIoPushUint32(&req, RES_SYSCAP);
    //将消息放入共享内存,标识操作为PUT,添加操作
    IpcIoPushUint32(&req, OP_PUT);
    //将字符串消息放入共享内存,首先存储字符串的长度,再拷贝字符串的内容。内容为sysCap
    IpcIoPushString(&req, sysCap);
    //标识是否注册
    IpcIoPushBool(&req, isReg);
    //构建响应结构
    IpcIo reply;
    void *replyBuf = NULL;
    //设置主endpoint地址
    SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
    //向主endpoint发送消息
    int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, &reply,
                       LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
    ret = -ret;
    if (ret == LITEIPC_OK)
    {
        //从reply中接收消息
        ret = IpcIoPopInt32(&reply);
    }
    if (replyBuf != NULL)
    {
        //释放内存
        FreeBuffer(endpoint, replyBuf);
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_AddSysCap ret = %d", ret);
    return ret;
}
获取syscap注册状态
/*
    函数功能:查询指定syscap的注册状态
    函数参数:@endpoint:当前进程的通信端点
             @sysCap:syscap名称
             @isReg:返回注册状态
    函数返回:查询成功 返回EC_SUCCESS,查询失败 返回EC_INVALID
    函数描述:向主endpoint发送查询请求,获取指定syscap的注册状态,保存在isReg中
*/
int32 SAMGR_GetSysCap(const Endpoint *endpoint, const char *sysCap, BOOL *isReg)
{
    if (endpoint == NULL)
    {
        return EC_INVALID;
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap begin");
    //定义请求结构
    IpcIo req;
    uint8 data[MAX_DATA_LEN];
    //将req与data缓冲区关联
    IpcIoInit(&req, data, MAX_DATA_LEN, 0);
    //将消息放入共享内存,内容为RES_SYSCAP
    IpcIoPushUint32(&req, RES_SYSCAP);
    //标识操作为GET,获取操作
    IpcIoPushUint32(&req, OP_GET);
    //将字符串消息放入共享内存,首先存储字符串的长度,再拷贝字符串的内容。内容为sysCap
    IpcIoPushString(&req, sysCap);
    //定义响应结构
    IpcIo reply;
    void *replyBuf = NULL;
    //设置主endpoint地址
    SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
    //使用当前进程的endpoint向主endpoint发送消息
    int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, &reply,
                       LITEIPC_FLAG_DEFAULT, (uintptr_t *)&replyBuf);
    ret = -ret;
    //初始化注册状态为false
    *isReg = FALSE;
    if (ret == LITEIPC_OK)
    {
        //从reply中读取消息
        ret = IpcIoPopInt32(&reply);
    }
    if (ret == EC_SUCCESS)
    {
        //从reply中获取注册状态
        *isReg = IpcIoPopBool(&reply);
    }
    if (replyBuf != NULL)
    {
        //释放内存
        FreeBuffer(endpoint, replyBuf);
    }
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SAMGR_GetSysCap ret = %d", ret);
    return ret;
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
发送查询所有syscap的请求
/*
    函数功能:发送查询所有syscap的请求消息
    函数参数:@endpoint:当前进程的通信端点
             @startIdx:查询的起始索引
             @reply:接收响应信息
             @replyBuf:接收响应的缓冲区
    函数描述:向主endpoint发送查询syscap的请求消息,操作类型为OP_ALL,查询的起始下标为startIdx。
             响应信息由reply和replyBuf返回。
*/
static int SendGetAllSysCapsRequest(const Endpoint *endpoint, uint32 startIdx, IpcIo *reply, void **replyBuf)
{
    //定义请求结构
    IpcIo req;
    uint8 data[MAX_DATA_LEN];
    //初始化IPC,将req与data关联
    IpcIoInit(&req, data, MAX_DATA_LEN, 0);
    //将消息放入共享内存,内容为RES_SYSCAP
    IpcIoPushUint32(&req, RES_SYSCAP);
    //操作为OP_ALL
    IpcIoPushUint32(&req, OP_ALL);
    //将消息放入共享内存,内容为查询的起始索引
    IpcIoPushUint32(&req, startIdx);
    //设置主endpoint的通信地址
    SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE};
    //向主endpoint发送消息,返回的信息存在reply和replyBuf中,LITEIPC_FLAG_DEFAULT表示发送并响应
    int ret = Transact(endpoint->context, samgr, INVALID_INDEX, &req, reply,
                       LITEIPC_FLAG_DEFAULT, (uintptr_t *)replyBuf);
    //记录当前操作日志
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "SendGetAllSysCapsRequest startIdx:%d, ret:%d!", startIdx, ret);
    return -ret;
}
处理服务和功能的访问策略
/*
    函数功能:获取服务和功能的访问地址和访问策略
    函数描述:向主endpoint发送服务名、功能名和router的下标,然后从响应消息中获取主endpoint为服务和功能生成的访问地址和访问策略。
             最后更新服务和功能的访问策略等信息。
*/
int SAMGR_ProcPolicy(const Endpoint *endpoint, const SaName *saName, int token)
{
    //参数检查
    if (endpoint == NULL || saName == NULL || token == INVALID_INDEX)
    {
        return EC_INVALID;
    }
    int ret = EC_INVALID;
    uint8 retry = 0;
    //设置svc标识
    SvcIdentity saInfo = {INVALID_INDEX, token, INVALID_INDEX};
    //一直重试直到成功,重试持续MAX_REGISTER_RETRY_TIMES * REGISTER_RETRY_INTERVAL
    while (retry < MAX_REGISTER_RETRY_TIMES)
    {
        ++retry;
        PolicyTrans *policy = NULL;
        uint32 policyNum = 0;
        //向主endpoint发送消息,注册服务和功能,然后从响应消息中获取主endpoint为服务和功能生成的访问地址和访问策略。
        ret = RegisterIdentity(endpoint->context, saName, &saInfo, &policy, &policyNum);
        if (ret != EC_SUCCESS || policy == NULL)
        {
            //注册失败
            SAMGR_Free(policy);
            continue;
        }
        HILOG_INFO(HILOG_MODULE_SAMGR, "Register server sa<%s, %s> id<%u, %u> retry:%d ret:%d!",
                   saName->service, saName->feature, saInfo.handle, saInfo.token, retry, ret);
        //通过saInfo匹配指定的router,为router添加访问策略
        ret = AddPolicyToRouter(endpoint, &saInfo, policy, policyNum);
        SAMGR_Free(policy);
        if (ret == EC_SUCCESS)
        {
            break;
        }//操作失败,睡眠一段时间重试
        sleep(REGISTER_RETRY_INTERVAL);
    }
    return ret;
}