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

100 篇文章 0 订阅
100 篇文章 1 订阅

往期知识点记录:

函数实现详解

注册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;
}
发送查询所有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;
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值