OpenHarmony轻量系统服务管理|samgr_server功能详解(五)

100 篇文章 0 订阅
100 篇文章 2 订阅

往期知识点记录:

函数实现详解

接着上文继续分析剩下的OP_ALL操作的处理函数以及本部分的其他函数。

请求资源为syscap操作类型为ALL的处理函数
/*
    函数功能:获取所有已注册的syscap
    函数参数:@server:SamgrServer
             @req:请求IO
             @reply:响应IO
    函数描述:从req消息中获取本次查询的起始下标。从起始下标startIdx开始遍历sysCapablitys。
             统计所有已注册的syscap数目,并记录下一次查询的起始下标,然后将已注册的syscap的name作为响应消息发送给请求者。
*/
void ProcGetAllSysCap(const SamgrServer *server, IpcIo *req, IpcIo *reply)
{
    //从req中获取消息,作为本次查询的起始下标
    uint32_t startIdx = IpcIoPopUint32(req);
    MUTEX_Lock(server->sysCapMtx);
    //获取SamgrServer对象的Vector
    Vector *sysCapablitys = &(server->sysCapabilitys);
    //获取集合大小
    int32 size = VECTOR_Num(sysCapablitys);
    if (size == INVALID_INDEX) {//sysCapablitys为NULL
        //构造响应消息,发送错误信息
        IpcIoPushInt32(reply, EC_FAILURE);
        IpcIoPushBool(reply, TRUE);
        IpcIoPushUint32(reply, startIdx);
        IpcIoPushUint32(reply, 0);
        MUTEX_Unlock(server->sysCapMtx);
        return;
    }//sysCapablitys不为NULL
    //定义下一次请求的下标,赋初始值。nextRequestIdx表示未查询的syscap的下标起始位置,每次查询完毕都会将它更新为本次查询结尾的下一个下标值。
    int32 nextRequestIdx = startIdx;
    //统计从startIdx开始已注册的syscap的数量,单次统计的数量不超过MAX_SYSCAP_NUM_PER_REPLY的值,并更新下一次查询的起始地址nextRequestIdx
    int32 replyNum = GetReplyNumAndNextReqIdx(sysCapablitys, startIdx, &nextRequestIdx);
    HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcGetAllSysCap replyNum: %d, size: %d, startIdx: %d, nextRequestIdx: %d",
                replyNum, size, startIdx, nextRequestIdx);
    //响应EC_SUCCESS
    IpcIoPushInt32(reply, EC_SUCCESS);
    //nextRequestIdx == size的值为true代表所有的syscap均已遍历。
    //nextRequestIdx == size的值为false代表还存在syscap没有被统计。请求者可以根据这个值发起第二次查询统计请求。
    IpcIoPushBool(reply, nextRequestIdx == size);
    //发送下一次查询的起始索引
    IpcIoPushUint32(reply, nextRequestIdx);
    //发送响应次数,即已注册的syscap的数量,用来标记后续发送的响应消息中syscap的个数
    IpcIoPushUint32(reply, replyNum);
    int32 cnt = 0;
    int32 i = startIdx;
    //遍历,将已注册的syscap的name发送到共享内存中
    for (; i < size && cnt < replyNum; i++) {
        //获取SysCapImpl实例
        SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
        if (serviceImpl->isRegister == FALSE) {
            continue;
        }
        //将已注册的syscap的name作为响应消息发送
        IpcIoPushString(reply, serviceImpl->name);
        cnt++;
    }
    MUTEX_Unlock(server->sysCapMtx);
}
统计所有注册的syscap
/*
    函数功能:统计已注册的syscap的数量
    函数参数:@sysCapablitys:存储syscap的vector
             @startIdx:查询的起始下标
             @nextRequestIdx:下一次查询的下标,即该值前的均已被查询
    函数返回:返回本次查询区间内已注册的syscap数量
    函数描述:统计已注册的syscap的数量,单次统计的数量不超过MAX_SYSCAP_NUM_PER_REPLY的值。
             将下一次查询的起始地址保存在nextRequestIdx中返回。
*/
static int32 GetReplyNumAndNextReqIdx(const Vector *sysCapablitys, int32 startIdx, int32 *nextRequestIdx)
{
    int32 registerNum = 0;
    //获取sysCapablitys对象中data实际占用空间,即元素个数
    int32 size = VECTOR_Num(sysCapablitys);
    //查询的起始下标
    int32 i = startIdx;
    //统计从startIdx开始,所有的注册数量。MAX_SYSCAP_NUM_PER_REPLY表示响应的最大数目,超出这个数目的需要进行第二次查询。
    for (; i < size && registerNum < MAX_SYSCAP_NUM_PER_REPLY; i++) {
        //获取指定索引对应的对象
        SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
        if (serviceImpl->isRegister == FALSE) {
            continue;
        }
        //统计已注册的数量
        registerNum++;
    }
    //更新下一次查询的下标,即下一次查询的起始位置
    *nextRequestIdx = i;
    //返回已注册的数量
    return registerNum;
}
设置主endpoint的地址
//通知内核,设置一个主EndPoint的地址,并给地址赋值
static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity)
{
    //通知内核,设置主EndPoint
    int ret = SetSaManager(context, MAX_SA_SIZE);
    if (ret != LITEIPC_OK) {
        //设置失败
        HILOG_FATAL(HILOG_MODULE_SAMGR, "Set sa manager<%d> failed!", ret);
        //设置sa管理器失败,需要重新启动才能恢复。
        exit(-ret);
    }
    //配置主endpoint的标识
    identity->handle = SAMGR_HANDLE;
    identity->token = SAMGR_TOKEN;
    identity->cookie = SAMGR_COOKIE;
    return EC_SUCCESS;
}
获取代理接口
//获取服务名为 PERMISSION_SERVICE 且功能名为 IPCAUTH 的API接口
static IpcAuthInterface *GetIpcAuthInterface(void)
{
    IpcAuthInterface *ipcAuth = NULL;
    //通过SamgrLite对象调用GetFeatureApi函数,获取服务名为 PERMISSION_SERVICE 且功能名为 IPCAUTH 的API接口
    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(PERMISSION_SERVICE, IPCAUTH);
    if (iUnknown == NULL) {
        HILOG_ERROR(HILOG_MODULE_SAMGR, "Get IpcAuthInterface: IUnknown NULL");
        return NULL;
    }
    //获取指定版本的IUnknown接口的子类对象
    (void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&ipcAuth);
    return ipcAuth;
}

写在最后

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值