往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理|系统功能的存储机制详解(一)
- OpenHarmony轻量系统服务管理|系统功能的存储机制详解(二)
- OpenHarmony轻量系统服务管理|系统功能的存储机制详解(三)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(一)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(二)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(三)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(四)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(五)
- OpenHarmony轻量系统服务管理|进程间通信的核心机制详解(六)
- OpenHarmony轻量系统服务管理|客户代理的工厂模式机制详解
- OpenHarmony轻量系统服务管理|进程间通信的客户端代理详解(一)
- OpenHarmony轻量系统服务管理|进程间通信的客户端代理详解(二)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(一)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(二)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(三)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(四)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(五)
- 持续更新中……
函数实现详解
接着上文继续分析剩下的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🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: